服务端订阅(MNS)
本文介绍如何配置服务端订阅,将产品下的设备状态变化消息推送到轻量消息队列(原 MNS) SMQ(Simple Message Queue (formerly MNS))队列中;服务器通过监听MNS队列接收设备状态变化消息。
前提条件
-
开通阿里云产品:
-
准备开发环境,本示例使用Java开发环境如下:
操作系统:Windows 10 64位
JDK版本:JDK8
集成开发环境:IntelliJ IDEA社区版
配置服务端订阅
首先在物联网平台控制台创建MNS服务端订阅,选择要订阅的消息类型。
-
登录物联网平台控制台。
在实例概览页签的全部环境下,找到对应的实例,单击实例卡片。
-
在左侧导航栏,选择,再单击创建产品,创建一个气体监测仪产品。
-
选择,在刚创建的气体监测仪产品下创建设备。
设备证书信息将会用于设备端SDK开发配置。
-
在左侧导航栏,选择,然后单击创建订阅,创建MNS服务端订阅。具体操作,请参见使用MNS服务端订阅。
说明首次设置推送到MNS时,需单击提示中的授权,进入RAM控制台同意授权IoT访问MNS。
本示例中,选择推送消息类型为设备状态变化通知,即该产品下所有设备的状态变化消息,都会被推送到MNS队列中。
订阅成功后,物联网平台会在MNS中,自动创建一个接收物联网平台消息的队列。队列名称格式为:
aliyun-iot-${yourProductKey}。您在配置MNS SDK监听消息时,需填入该队列名称。在订阅列表中,单击MNS右侧的图标,可查看MNS队列名称。
配置服务端MNS SDK接收消息
本示例使用MNS Java SDK Demo。
-
访问MNS Java SDK版本说明,下载sample包文件,并解压缩。
本示例使用sample包文件为aliyun-sdk-mns-samples-1.1.9.1.zip。
-
在IntelliJ IDEA中,导入工程aliyun-sdk-mns-samples-1.1.9.1文件夹。
-
在计算机的本地目录C:\Users\${YourComputerUserName}下,添加一个PROPERTIES类型文件.aliyun-mns.properties,并在文件中输入MNS访问身份认证信息,格式如下:
说明Linux系统用户目录为/home/YOURNAME/,Windows系统用户目录为C:\Users\YOURNAME。
mns.accountendpoint=http://${your_accountId}.mns.${your_regionId}.aliyuncs.com mns.accesskeyid=${your_accesskeyid} mns.accesskeysecret=${your_accesskeysecret}参数
说明
accountendpoint
您的MNS服务Endpoint。请在轻量消息队列(原 MNS)控制台,选择队列所在地域单击队列的详情查看。
accesskeyid
您的阿里云账号的AccessKey ID和AccessKey Secret。
登录物联网平台控制台,将鼠标移至账号头像上,然后单击AccessKey管理,获取AccessKey ID和AccessKey Secret。
accesskeysecret
-
在src\main\java\com.aliyun.mns.sample.Queue目录下的ComsumerDemo文件中,配置物联网平台自动创建的轻量消息队列(原 MNS)名称。
public static void main(String[] args) { CloudAccount account = new CloudAccount( ServiceSettings.getMNSAccessKeyId(), ServiceSettings.getMNSAccessKeySecret(), ServiceSettings.getMNSAccountEndpoint()); MNSClient client = account.getMNSClient(); //client初始化 // 提取消息 try{ CloudQueue queue = client.getQueueRef("aliyun-iot-a1eN7La****");// 替换为物联网平台自动创建的队列 for (int i = 0; i < 10; i++) { Message popMsg = queue.popMessage(); //长轮询等待时间 if (popMsg != null){ System.out.println("message handle: " + popMsg.getReceiptHandle()); System.out.println("message body: " + popMsg.getMessageBodyAsString()); //获取原始消息 System.out.println("message id: " + popMsg.getMessageId()); System.out.println("message dequeue count:" + popMsg.getDequeueCount()); //<<to add your special logic.>> //从队列中删除消息 queue.deleteMessage(popMsg.getReceiptHandle()); System.out.println("delete message successfully.\n"); } } } catch (Exception e) { e.printStackTrace(); } } -
运行程序文件ComsumerDemo.java。
配置设备端SDK
-
访问设备接入Link SDK,选择Java SDK。
-
在Java Link SDK的环境要求与配置中,下载Java SDK Demo,然后解压缩。
-
在IntelliJ IDEA中,导入工程JavaLinkKitDemo。
-
在device_id文件中,填入设备证书信息。
{ "productKey": "xxx", "deviceName": "Esensor", "productSecret": "", "deviceSecret": "1xxx?2" } -
在src\main\java\com.aliyun.alink.devicesdk.demo目录下的MqttSample文件中,将publish对应的Topic配置为您的设备Topic。
public class MqttSample extends BaseSample { final static String TAG = "MqttSample"; public MqttSample(String pk, String dn) { super(pk, dn); } /** * 发布接口示例 */ public void publish() { MqttPublishRequest request = new MqttPublishRequest(); // topic 用自根据实际场景填写 request.topic = "/sys/" + productKey + "/" + deviceName + "/thing/deviceinfo/update"; } } -
在src\main\java\com.aliyun.alink.devicesdk.demo目录下的HelloWorld文件中,填入设备接入信息。
设备接入信息的获取方法,请参见查看和配置实例终端节点信息(Endpoint)。其中
channelHost的拼接格式为{productKey}.iot-as-mqtt.{region}.aliyuncs.com:1883。示例代码:public void init(final DeviceInfoData deviceInfoData) { this.pk = deviceInfoData.productKey; this.dn = deviceInfoData.deviceName; LinkKitInitParams params = new LinkKitInitParams(); /** * 设置 Mqtt 初始化参数 */ IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = deviceInfoData.productKey; config.deviceName = deviceInfoData.deviceName; config.deviceSecret = deviceInfoData.deviceSecret; config.channelHost = pk + ".iot-as-mqtt." + deviceInfoData.region + ".aliyuncs.com:1883"; /** * 是否接受离线消息 * 对应 mqtt 的 cleanSession 字段 */ // ... } -
运行设备连接的程序文件:HelloWorld.java。
结果验证
设备端SDK运行后,设备上线消息通过服务端订阅发送到轻量消息队列(原 MNS)中。轻量消息队列(原 MNS)SDK从队列中接收消息,并同时将已接收的消息从队列中删除。
以下示例展示轻量消息队列(原 MNS)SDK接收并删除消息。
message handle: 519xxx...AgMA==
message body:
{"payload":"eyJsYXN0xxx...IiwiY2xpZW5xxx...","topic":"/as/mqtt/status/xxx/device1","messageid":15xxx,"timestamp":1661158432}
message id: 51xxx...C49
message dequeue count:1
delete message successfully.