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

背景信息

  • 向全量在线设备广播消息

    业务服务器调用PubBroadcast接口,传入指定产品的ProductKeyMessageContent消息内容,产品的全量在线设备可通过广播Topic/sys/${productKey}/${deviceName}/broadcast/request/${MessageId},收到MessageContent消息内容。

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

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

    广播通信
  • 向订阅了指定Topic的所有设备广播消息

    设备端订阅相同的广播Topic,业务服务器调用PubBroadcast接口,传入指定产品的ProductKeyMessageContent消息内容和要接收广播消息的Topic全称(格式为:/broadcast/${productKey}/自定义字段),已订阅广播Topic的在线设备,收到MessageContent消息内容。

    重要
    • 广播Topic是在设备开发时编码定义的,无需在物联网平台控制台创建。
    • 一个广播Topic最多可被1,000个设备订阅。如果您的设备超过数量限制,您可以对设备进行分组。例如,如果您有5,000个设备,您可以将设备按每组1,000个,而分成5组。您需要分5次调用广播Topic,自定义字段分别设置为group1、group2、group3、group4、group5,然后让每组设备分别订阅各自分组的广播Topic。

    广播接口调用的更多详细说明,请参见PubBroadcast

使用限制

  • 广播消息仅推送给产品下当前在线的设备。
  • 指定在线设备广播时,需指定Topic订阅广播,广播接口最大调用频次:1次/秒。
  • 全量在线设备广播时,无需订阅广播Topic,广播接口最大调用频次:1次/分钟。
  • 广播消息体报文最大为64 KB。
重要 广播消息不会被实例的消息上下行TPS规格限流。例如,消息上下行TPS为100条/秒,当前在线设备为500个时,每次调用广播接口,消息不会只发送给100个在线设备,而是可以发送给500个在线设备。

准备开发环境

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

添加Maven项目依赖

新建项目,在pom.xml中,添加以下Maven依赖。

说明 以下IoT Java SDK版本为示例值,您可在OpenAPI Explorer页面查看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>4.5.6</version>
  </dependency>
  <dependency>
      <groupId>com.aliyun</groupId>
      <artifactId>aliyun-java-sdk-iot</artifactId>
      <version>7.41.0</version>
  </dependency>
  <dependency>
    <groupId>com.aliyun.openservices</groupId>
    <artifactId>iot-client-message</artifactId>
    <version>1.1.2</version>
  </dependency>
</dependencies>

创建产品和设备

  1. 登录物联网平台控制台
  2. 实例概览页面,选择目标环境,找到对应的实例,单击实例ID或备注名称。
    重要 目前仅开通企业版实例服务的地域下,执行此步骤。其他地域,请跳过此步骤。地域及实例的支持说明,请参见实例概述
    实例概览
  3. 在左侧导航栏,单击设备管理 > 产品
  4. 单击创建产品,创建智能门锁产品。具体操作,请参见创建产品
  5. 在左侧导航栏,单击设备管理 > 设备,然后在智能门锁产品下,创建三个设备。具体操作,请参见批量创建设备

配置设备端SDK

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

      productKeydeviceNamedeviceSecret是设备证书信息,请在物联网平台控制台,对应实例下,选择设备管理 > 设备,单击设备对应的查看,进入设备详情页获取。

      region是设备所属地域。region的表达方法,请参见地域列表

    • 设置初始化连接参数,包括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;

      channelHost是MQTT接入地址,公共实例和企业版实例中接入地址的获取方法,请参见查看实例终端节点

    • 初始化连接。
      //连接并设置连接成功以后的回调函数。
      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\"}"));
    //设置实例ID。
    request.setIotInstanceId("iot-cn-***");
  • 服务端发送广播消息。
    try {
        PubBroadcastResponse response = client.getAcsResponse(request);
    System.out.println("broadcast pub success: broadcastId =" + response.getMessageId());
    } catch (Exception e) {
        System.out.println(e);
    }

验证操作

先运行各设备的Link SDK代码,使设备上线,然后运行云端SDK代码,调用接口PubBroadcast向设备广播消息。

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

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

门锁1:

门锁1

门锁2:

门锁2

门锁3:

门锁3

附录:Demo

查看以下完整的配置代码Demo,其中包含物联网平台云端SDK和设备端SDK示例。