物联网平台支持广播通信,即向指定产品下的全量在线设备发送消息。设备无需订阅广播Topic,即可收到服务器发送的广播消息。下面介绍广播通信的具体配置流程。

背景信息

厂家有多个智能门锁接入物联网平台,现在需要业务服务器向全部在线设备发送一条相同的指令,使某个密码失效。

业务服务器调用PubBroadcast接口,指定产品ProductKey和MessageContent消息内容,产品的全量在线设备就会在广播Topic/sys/${productKey}/${deviceName}/broadcast/request/${MessageId}下,收到MessageContent消息内容。

广播Topic中的MessageId是云端生成的消息ID,成功发送消息后,将作为PubBroadcast接口的返回数据返回业务服务器。

广播通信

使用限制

  • 广播消息仅推送到产品下当前在线的设备。
  • 广播接口最大调用频次:1次/分钟。
  • 广播消息体报文最大64 KB。

准备开发环境

本示例中,设备端和云端均使用Java语言的SDK,需先准备Java开发环境。可从Java 官方网站下载、安装Java开发环境。

新建项目,添加以下Maven依赖,导入阿里云设备端SDK和云端SDK。

<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.aliyun</groupId>
      <artifactId>aliyun-java-sdk-core</artifactId>
      <version>3.7.1</version>
  </dependency>
  <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-iot</artifactId>
      <version>7.6.0</version>
  </dependency>
  <dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>iot-client-message</artifactId>
    <version>1.1.2</version>
  </dependency>
</dependencies>

创建产品和设备

  1. 登录物联网平台控制台
  2. 在左侧导航栏,单击设备管理 > 产品
  3. 单击创建产品,创建智能门锁产品。

    详细操作指导,请参见创建产品

  4. 在左侧导航栏,单击设备,然后在刚创建的智能门锁产品下,创建两个设备。

    详细操作指导,请参见批量创建设备

配置设备端SDK

配置Link SDK接入物联网平台。

  • 配置设备端接入物联网平台。
    • 配置设备认证信息。
      final String productKey = "<yourProductKey>";
      final String deviceName = "<yourDeviceName>";
      final String deviceSecret = "<yourDeviceSecret>";
      final String region = "<yourRegionID>";

      productKeydeviceNamedeviceSecret是设备证书信息,请选择设备管理 > 设备,单击设备对应的查看,进入设备详情页查看。

      region是设备所属地域。region的表达方法,请参见地域和可用区中的Region ID。

    • 设置初始化连接参数,包括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;
    • 初始化连接。
      //连接并设置连接成功以后的回调函数。
      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);
           }
       });
  • 在回调函数onInitDone中,通过前缀来识别广播Topic,广播Topic的前缀为:/sys/${productKey}/${deviceName}/broadcast/request/
    public void onInitDone(InitResult initResult) {
    
                    //设置下行消息到来时的回调函数。
                    IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
                        //此处定义收到下行消息以后的回调函数。
                        @Override
                        public void onNotify(String connectId, String topic, AMessage aMessage) {
    
                            //过滤得到广播消息。
                            if(topic.startsWith(broadcastTopic)){
                                System.out.println(
                                        "received broadcast message from topic=" + topic + ",\npayload=" + 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);
                }

配置服务端SDK

配置云端Java SDK发送广播消息。

  • 配置身份认证信息。
     String regionId = "<yourRegionID>";
     String accessKey = "<yourAccessKey>";
     String accessSecret = "<yourAccessSecret>";
     final String productKey = "<yourProductKey>";
  • 配置服务端调用云端API PubBroadcast广播消息。
    //设置client的参数。
    DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKey, accessSecret);
    IAcsClient client = new DefaultAcsClient(profile);
    PubBroadcastRequest request = new PubBroadcastRequest();
    //设置广播消息的产品productKey。
    request.setProductKey(productKey);
    //设置消息的内容,一定要用base64编码,否则乱码。
    request.setMessageContent(Base64.encode("{\"pwd\":\"2892nd6Y\"}"));
  • 服务端发送广播消息。
    try {
        PubBroadcastResponse response = client.getAcsResponse(request);
    System.out.println("broadcast pub success: broadcastId =" + response.getMessageId());
    } catch (Exception e) {
        System.out.println(e);
    }

验证操作

云端SDK中,向设备端广播的消息内容为:"{\"pwd\":\"2892nd6Y\"}"

设备端本地日志都将显示收到广播消息:{\"pwd\":\"2892nd6Y\"}

门锁1:

门锁1

门锁2:

门锁2

门锁3:

门锁3

附录:Demo

单击PubBroadcastDemo,下载、查看完整的配置代码Demo。Demo包中包含云端SDK和设备端SDK示例。