使用MQTT協議接入的裝置和物聯網平台,通過訂閱Topic或向Topic發布訊息的方式進行通訊。Topic分為系統Topic、物模型Topic和自訂Topic,其中自訂Topic需要使用者在控制台定義。 本文為您介紹裝置使用自訂Topic與物聯網平台進行上下行通訊,以及物聯網平台和商務服務器之間通訊的步驟。
背景資訊
本樣本中,電子溫度計通過訂閱自訂Topic接收指令,通過向自訂Topic發布訊息從而上報溫度,物聯網平台將收到的溫度資訊通過AMQP服務端轉寄到使用者服務器,使用者服務器調用Pub介面向自訂Topic發布訊息從而實現對裝置的遠程精度設定。
準備開發環境
本樣本中,裝置端和雲端均使用Java語言的SDK,需先準備Java開發環境。您可從Java官方網站下載並安裝Java開發環境。
本樣本使用環境如下:
作業系統:Windows 10 64位
JDK版本:JDK8
整合式開發環境:IntelliJ IDEA社區版
建立產品和裝置
登入物聯網平台控制台。
在執行個體概覽頁簽的全部環境下,找到對應的執行個體,單擊執行個體卡片。
在左側導覽列,單擊 。
單擊建立產品,建立溫度計產品,擷取productKey,例如
a1uzcH0****
。詳細操作指導,請參見建立產品。
建立產品成功後,單擊該產品對應的查看。
在產品詳情頁面的Topic類列表頁簽下,單擊自訂Topic,增加自訂Topic類。
詳細操作指導,請參見使用自訂Topic通訊。
本樣本中,定義了以下兩個Topic類:
裝置發布訊息Topic:/a1uzcH0****/${deviceName}/user/devmsg,許可權為發布。
裝置訂閱訊息Topic:/a1uzcH0****/${deviceName}/user/cloudmsg,許可權為訂閱。
在服務端訂閱頁簽下,單擊建立訂閱,設定AMQP服務端訂閱,訂閱裝置上報訊息到預設消費組。
裝置上報訊息包含自訂Topic訊息和物模型訊息。詳細操作和說明,請參見配置AMQP服務端訂閱。
在左側導覽列,選擇 ,然後在剛建立的溫度計產品下,添加裝置device1,擷取裝置認證ProductKey、DeviceName和DeviceSecret。
詳細操作指導,請參見單個建立裝置。
裝置發送訊息給伺服器
流程圖:
在整個流程中:
伺服器通過AMQP用戶端接收訊息,需配置AMQP用戶端接入物聯網平台,監聽裝置訊息。具體操作,請參見Java SDK接入樣本。
重要AMQP訂閱訊息的消費組,必須與裝置在相同的物聯網平台執行個體下。
配置裝置端SDK接入物聯網平台,並發送訊息。
配置裝置認證資訊。
final String productKey = "a1uzcH0****"; final String deviceName = "device1"; final String deviceSecret = "uwMTmVAMnxB****"; final String region = "cn-shanghai"; final String iotInstanceId = "iot-2w****";
實際業務情境中,您需修改以下參數值。
參數
樣本
說明
productKey
a1uzcH0****
裝置認證資訊。您可在物聯網平台控制台的裝置詳情頁面查看。具體操作,請參見查看具體裝置資訊。
deviceName
device1
deviceSecret
uwMTmVAMnxB****
region
cn-shanghai
您物聯網平台裝置所在地區的Region ID。Region ID表達方法,請參見地區列表。
iotInstanceId
iot-2w****
裝置所屬執行個體的ID。
您可在控制台的執行個體概覽頁面查看。
若有ID值,必須傳入該ID值。
若無執行個體概覽頁面或ID值,傳入空值,即
iotInstanceId = ""
。
設定初始化串連參數,包括MQTT串連配置、裝置資訊和初始物模型屬性。
LinkKitInitParams params = new LinkKitInitParams(); //LinkKit底層是MQTT協議,設定MQTT的配置。 IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = productKey; config.deviceName = deviceName; config.deviceSecret = deviceSecret; config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883"; //裝置的資訊。 DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.productKey = productKey; deviceInfo.deviceName = deviceName; deviceInfo.deviceSecret = deviceSecret; //報備的裝置初始狀態。 Map<String, ValueWrapper> propertyValues = new HashMap<String, ValueWrapper>(); params.mqttClientConfig = config; params.deviceInfo = deviceInfo; params.propertyValues = propertyValues;
實際業務情境中,您需修改以下參數值。
參數
樣本
說明
config.channelHost
config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
MQTT裝置接入網域名稱。
舊版公用執行個體:
config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
。新版公用執行個體和企業版執行個體:
config.channelHost = iotInstanceId + ".mqtt.iothub.aliyuncs.com:1883";
。
初始化串連。
//串連並設定串連成功以後的回呼函數。 LinkKit.getInstance().init(params, new ILinkKitConnectListener() { @Override public void onError(AError aError) { System.out.println("Init error:" + aError); } //初始化成功以後的回調。 @Override public void onInitDone(InitResult initResult) { System.out.println("Init done:" + initResult); } });
裝置發送訊息。
裝置端串連物聯網平台後,向自訂的Topic發送訊息。您需將onInitDone函數內容替換為以下內容:
@Override public void onInitDone(InitResult initResult) { //設定Pub訊息的Topic和內容。 MqttPublishRequest request = new MqttPublishRequest(); request.topic = "/" + productKey + "/" + deviceName + "/user/devmsg"; request.qos = 0; request.payloadObj = "{\"temperature\":35.0, \"time\":\"sometime\"}"; //發送訊息並設定成功以後的回調。 LinkKit.getInstance().publish(request, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { System.out.println("onResponse:" + aResponse.getData()); } @Override public void onFailure(ARequest aRequest, AError aError) { System.out.println("onFailure:" + aError.getCode() + aError.getMsg()); } }); }
實際業務情境中,您需修改以下參數值。
參數
樣本
說明
request.topic
"/" + productKey + "/" + deviceName + "/user/devmsg"
具有發布許可權的自訂Topic。
request.payloadObj
"{\"temperature\":35.0, \"time\":\"sometime\"}"
自訂的訊息內容。
伺服器收到訊息如下:
Message {payload={"temperature":35.0, "time":"sometime"}, topic='/a1uzcH0****/device1/user/devmsg', messageId='1131755639450642944', qos=0, generateTime=1558666546105}
伺服器發送訊息給裝置
流程圖:
配置裝置端SDK訂閱Topic。
配置裝置認證資訊、設定初始化串連參數、初始化串連,請參見裝置發送訊息給伺服器中的相應範例程式碼。
裝置要接收伺服器發送的訊息,還需訂閱訊息Topic。
配置裝置端訂閱Topic樣本如下:
//初始化成功以後的回調。 @Override public void onInitDone(InitResult initResult) { //設定訂閱的Topic。 MqttSubscribeRequest request = new MqttSubscribeRequest(); request.topic = "/" + productKey + "/" + deviceName + "/user/cloudmsg"; request.isSubscribe = true; //發出訂閱請求並設定訂閱成功或者失敗的回呼函數。 LinkKit.getInstance().subscribe(request, new IConnectSubscribeListener() { @Override public void onSuccess() { System.out.println(""); } @Override public void onFailure(AError aError) { } }); //設定訂閱的下行訊息到來時的回呼函數。 IConnectNotifyListener notifyListener = new IConnectNotifyListener() { //此處定義收到下行訊息以後的回呼函數。 @Override public void onNotify(String connectId, String topic, AMessage aMessage) { System.out.println( "received message from " + topic + ":" + new String((byte[])aMessage.getData())); } @Override public boolean shouldHandle(String s, String s1) { return false; } @Override public void onConnectStateChange(String s, ConnectState connectState) { } }; LinkKit.getInstance().registerOnNotifyListener(notifyListener); }
其中,
request.topic
值需修改為具有訂閱許可權的自訂Topic。配置雲端SDK調用物聯網平台介面Pub發布訊息。參數說明,請參見Pub,使用說明,請參見Java SDK使用說明。
設定身份認證資訊。
String regionId = "cn-shanghai"; String accessKey = "LTAI4GFGQvKuqHJhFaj****"; String accessSecret = "iMS8ZhCDdfJbCMeA005sieKe****"; final String productKey = "a1uzcH0****"; final String deviceName = "device1"; final String iotInstanceId = "iot-2w****";
實際業務情境中,您需修改以下參數值。
參數
樣本
說明
accessKey
LTAI4GFGQvKuqHJhFaj****
您的阿里雲帳號的AccessKey ID和AccessKey Secret。
登入物聯網平台控制台,將滑鼠移至帳號頭像上,然後單擊AccessKey管理,擷取AccessKey ID和AccessKey Secret。
說明如果使用RAM使用者,您需授予該RAM使用者管理物聯網平台的許可權(AliyunIOTFullAccess),否則將串連失敗。授權方法請參見授權RAM使用者訪問物聯網平台。
accessSecret
iMS8ZhCDdfJbCMeA005sieKe****
productKey
a1uzcH0****
裝置認證資訊。您可在物聯網平台控制台的裝置詳情頁面查看。具體操作,請參見查看具體裝置資訊。
deviceName
device1
region
cn-shanghai
您物聯網平台裝置所在地區的Region ID。Region ID表達方法,請參見地區列表。
iotInstanceId
iot-2w****
裝置所屬執行個體的ID。
您可在控制台的執行個體概覽頁面查看。
若有ID值,必須傳入該ID值。
若無執行個體概覽頁面或ID值,傳入空值,即
iotInstanceId = ""
。
設定串連參數。
//設定client的參數。 DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKey, accessSecret); IAcsClient client = new DefaultAcsClient(profile);
設定訊息發布參數。
PubRequest request = new PubRequest(); request.setIotInstanceId(iotInstanceId); request.setQos(0); //設定發布訊息的Topic。 request.setTopicFullName("/" + productKey + "/" + deviceName + "/user/cloudmsg"); request.setProductKey(productKey); //設定訊息的內容,一定要用Base64編碼,否則亂碼。 request.setMessageContent(Base64.encode("{\"accuracy\":0.001,\"time\":now}"));
實際業務情境中,您需修改調用介面的請求參數。詳細說明,請參見Pub。
發送訊息。
try { PubResponse response = client.getAcsResponse(request); System.out.println("pub success?:" + response.getSuccess()); } catch (Exception e) { System.out.println(e); }
裝置端接收到的訊息如下:
msg = [{"accuracy":0.001,"time":now}]
附錄:程式碼範例
實際業務情境中,請按照上文描述,修改相關代碼及相關參數的值。
下載Pub/Sub demo,包含本樣本的雲端SDK和裝置端SDK配置代碼Demo。
AMQP用戶端接入物聯網平台樣本,請參見: