物联网平台支持广播通信,即向产品下的所有设备发送消息。设备仅需订阅广播Topic,即可收到服务器发送的广播消息。本文介绍广播通信的具体配置流程。

背景信息

厂家有多个温度计接入物联网平台,现在需要服务器向全部温度计发送一条相同的精度指令。

设备端订阅相同的广播Topic,服务器调用PubBroadcast向该Topic发布消息。



准备开发环境

本文示例中,设备端和云端均使用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>6.9.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 Kit的Java SDK接入物联网平台,并订阅广播Topic。

  • 配置设备端接入物联网平台。
    • 配置设备认证信息。
      final String productKey = "XXXXXX";
      final String deviceName = "XXXXXX";
      final String deviceSecret = "XXXXXXXXX";
      final String region = "XXXXXX";

      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);
           }
       });
  • 设备端订阅广播Topic。在回调函数onInitDone中,设置发送订阅请求。

    广播Topic无需创建,直接按照指定格式填入:/broadcast/${productKey}/自定义字段。

    本示例中的广播Topic为:"/broadcast/" + productKey + "/userDefine"

    说明 设备端SDK和云端SDK上配置的广播Topic必须一致。
    public void onInitDone(InitResult initResult) {
          //设置订阅的广播Topic,不需要在控制台上创建topic
         MqttSubscribeRequest request = new MqttSubscribeRequest();
         request.topic = "/broadcast/" + productKey + "/userDefine";
         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);
     }

配置服务端SDK

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

  • 配置身份认证信息。
     String regionId = "您设备所处区域regionId";
     String accessKey = "您的阿里云账号accessKey";
     String accessSecret = "您的阿里云账号accessSecret";
     final String productKey = "您的产品productKey";
  • 配置服务端调用云端API PubBroadcast广播消息。
    //设置client的参数
     DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKey, accessSecret);
     IAcsClient client = new DefaultAcsClient(profile);
    
     PubBroadcastRequest request = new PubBroadcastRequest();
     //设置广播消息的Topic,需与设备端订阅的广播Topic一致
     request.setTopicFullName("/broadcast/" + productKey + "/userDefine");
     request.setProductKey(productKey);
     //设置消息的内容,请务必用base64编码,否则会出现乱码
     request.setMessageContent(Base64.encode("{\"accuracy\":0.001,\"time\":now}"));
  • 服务端发送广播消息。
    try {
        PubBroadcastResponse response = client.getAcsResponse(request);
        System.out.println("broadcast pub success?:" + response.getSuccess());
    } catch (Exception e) {
        System.out.println(e);
    }

验证操作

云端SDK中,向设备端广播的消息内容为:"{\"accuracy\":0.001,\"time\":now}"

温度计0号和温度计1号日志都显示了收到了广播消息:{"accuracy":0.001,"time":now}

附录:Demo

单击BroadcastDemo,下载、查看完整的配置代码Demo。