概述
物聯網平臺提供NTP服務,解決嵌入式設備資源受限,系統不包含NTP服務,端上沒有精確時間戳的問題。物聯網平臺借鑑NTP協議原理,將雲端作爲NTP服務器。設備端發送一個特定Topic給雲端,payload中帶上發送時間。雲端回覆時在payload中加上雲端的接收時間和發送時間。設備端收到回覆後,再結合自己本地當前時間,得出一共4個時間。一起計算出設備端與雲端的時間差,從而得出端上當前的精確時間。本文主要演示如果使用JAVA SDK實現相關功能。
實驗步驟
1、相關Topic
請求Topic:/ext/ntp/${YourProductKey}/${YourDeviceName}/request
響應Topic:/ext/ntp/${YourProductKey}/${YourDeviceName}/response
2、pom.xml
<repositories>
<repository>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.aliyun.alink.linksdk</groupId>
<artifactId>iot-linkkit-java</artifactId>
<version>1.2.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.40</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>iot-java-sdk</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
3、Code Sample
import com.aliyun.alink.dm.api.DeviceInfo;
import com.aliyun.alink.dm.api.InitResult;
import com.aliyun.alink.dm.api.IoTApiClientConfig;
import com.aliyun.alink.linkkit.api.ILinkKitConnectListener;
import com.aliyun.alink.linkkit.api.IoTMqttClientConfig;
import com.aliyun.alink.linkkit.api.LinkKit;
import com.aliyun.alink.linkkit.api.LinkKitInitParams;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttPublishRequest;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttSubscribeRequest;
import com.aliyun.alink.linksdk.cmp.core.base.AMessage;
import com.aliyun.alink.linksdk.cmp.core.base.ARequest;
import com.aliyun.alink.linksdk.cmp.core.base.AResponse;
import com.aliyun.alink.linksdk.cmp.core.base.ConnectState;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectNotifyListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSendListener;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSubscribeListener;
import com.aliyun.alink.linksdk.tools.AError;
public class DeviceNTPDemo {
public static void main(String[] args) {
String regionId = "cn-shanghai";
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = "******";
deviceInfo.deviceName = "******";
deviceInfo.deviceSecret = "******";
LinkKitInitParams params = new LinkKitInitParams();
IoTMqttClientConfig config = new IoTMqttClientConfig();
config.productKey = deviceInfo.productKey;
config.deviceName = deviceInfo.deviceName;
config.deviceSecret = deviceInfo.deviceSecret;
config.channelHost = deviceInfo.productKey + ".iot-as-mqtt." + regionId + ".aliyuncs.com:1883";
params.mqttClientConfig = config;
params.connectConfig = new IoTApiClientConfig();
params.deviceInfo = deviceInfo;
/**建立連接**/
LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
@Override
public void onError(AError aError) {
System.out.println("初始化失敗 " + aError.getMsg());
}
@Override
public void onInitDone(InitResult initResult) {
System.out.println("初始化成功 " + initResult.tsl);
String pd = deviceInfo.productKey + "/" + deviceInfo.deviceName;
// 1、ntp 請求 Topic
String requestNtpTopic = "/ext/ntp/"+pd+"/request";
// 2、ntp 響應 Topic
String responseNtpTopic = "/ext/ntp/"+pd+"/response";
// 訂閱Topic
MqttSubscribeRequest upgradeTopicRequest = new MqttSubscribeRequest();
upgradeTopicRequest.topic = responseNtpTopic;
upgradeTopicRequest.isSubscribe = true;
LinkKit.getInstance().subscribe(upgradeTopicRequest, new IConnectSubscribeListener(){
@Override
public void onSuccess() {
System.out.println("訂閱成功");
}
@Override
public void onFailure(AError aError) {
System.out.println("訂閱失敗" + aError.getMsg());
}
});
// 註冊ota下行監聽
LinkKit.getInstance().registerOnNotifyListener(new IConnectNotifyListener() {
@Override
public void onNotify(String s, String s1, AMessage aMessage) {
System.out.println("ntp監聽響應:");
System.out.println(new String((byte[])aMessage.getData()));
}
@Override
public boolean shouldHandle(String s, String s1) {
return false;
}
@Override
public void onConnectStateChange(String s, ConnectState connectState) {
System.out.println("連接狀態發生變化 :" + s + connectState);
}
});
// 上報設備時間
MqttPublishRequest progressTopicRequest = new MqttPublishRequest();
progressTopicRequest.topic = requestNtpTopic;
progressTopicRequest.payloadObj = "{\n" +
" \"deviceSendTime\":\"1567336250000\"\n" +
"}";
progressTopicRequest.qos = 0;
LinkKit.getInstance().publish(progressTopicRequest, new IConnectSendListener() {
@Override
public void onResponse(ARequest aRequest, AResponse aResponse) {
System.out.println("ntp請求成功 " + aResponse.getData());
}
@Override
public void onFailure(ARequest aRequest, AError aError) {
System.out.println("ntp請求失敗 " + aError.getMsg());
}
});
}
});
}
}
4、請求結果
{"deviceSendTime":"1567336250000","serverSendTime":"1567336282175","serverRecvTime":"1567336282175"}
5、時間計算方法
設備端收到服務端的時間記爲${deviceRecvTime},則設備上的精確時間爲:(${serverRecvTime} + ${serverSendTime} + ${deviceRecvTime} - ${deviceSendTime}) / 2