You can create custom topic categories in the IoT Platform console for messaging between devices and servers. A device can send messages to a custom topic that belongs to a topic category. Then, your server can receive the messages from the topic by using an AMQP SDK. Your server can also call the Pub API operation to publish messages to the custom topic, and the device can obtain these messages from the topic. When you use custom topics for communication, , the Thing Specification Language (TSL) model is not used, and you can define the data structure for messages in custom topics.

Background information

In this example, an electronic thermometer communicates with a server at a regular interval. The thermometer sends real-time temperature data to the server, and the server sends commands to the thermometer to adjust the data precision.

Communication based on custom topics

Prepare the development environment

In this example, devices and IoT Platform use SDKs for Java. Therefore, you must prepare a Java development environment. You can download the Java development environment from the official website and install the environment on premises.

In this example, the development environment consists of the following components:

Create a product and a device

  1. Log on to the IoT Platform console.
  2. On the Overview page, find the instance that you want to manage and click the instance name to go to the Instance Details page.
    Notice Enterprise Edition instances are available in the China (Shanghai) and Japan (Tokyo) regions. If the Enterprise Edition instances are unavailable in the region that you select, skip this step.
    Overview
  3. In left-side navigation pane, choose Devices > Products.
  4. Click Create Product to create a thermometer product. After the product is created, go to the Products page and obtain the ProductKey, such as a1uzcH0****.
    For information about how to create a product, see Create a product.
  5. After the thermometer product is created, find the product on the Products page and click View in the Actions column.
  6. On the Product Details page, click the Topic Categories tab. On this tab, click Topic Category to add a custom topic category.

    For information about how to create a topic category, see Custom topics.

    In this example, the following topic categories are required:

    • /a1uzcH0****/${deviceName}/user/devmsg: Set the Device Operation Authorizations parameter to Publish. Devices can send messages to this topic.
    • /a1uzcH0****/${deviceName}/user/cloudmsg: Set the Device Operation Authorizations parameter to Subscribe. Devices can subscribe to this topic.
  7. On the Server-side Subscription tab, click Create Subscription to create an AMQP server-side subscription. Set the Message Type parameter to Device Upstream Notification and select the default consumer group.
    Device Upstream Notification indicates the messages that are submitted by devices, including messages in custom topics and TSL messages. For information about how to configure an AMQP server-side subscription, see Configure an AMQP server-side subscription.
  8. In the left-side navigation pane, click Devices > Devices. Then, create a device named device1 under the thermometer product. Obtain the device certificate information, including the values of ProductKey, DeviceName, and DeviceSecret.
    For information about how to create a device, see Create a device.

Configure the device to send a message to the server

The following figure shows how the device sends a message to the server.

Communication based on custom topics

This section describes how to configure the server and device to implement the messaging process.

  • Connect your AMQP client to IoT Platform, and configure the client to listen to messages from the device. The server receives messages by using the AMQP client. For more information, see Connect a client to IoT Platform by using the SDK for Java.
    Notice The consumer group of the AMQP client must be in the same IoT Platform instance as the device.
  • Configure the device SDK to connect the device to IoT Platform and enable the device to send messages.
    • Configure the parameters to authenticate the device.
      final String productKey = "a1uzcH0****";
      final String deviceName = "device1";
      final String deviceSecret = "uwMTmVAMnxB****";
      final String region = "cn-shanghai";
      final String iotInstanceId = "iot-2w****";

      You must configure the parameters that are described in the following table based on your business requirements.

      Parameter Example Description
      productKey a1uzcH0**** The information about the device certificate. You can view the value of this parameter on the Device Details page in the IoT Platform console.For more information, see View detailed information about a device.
      deviceName device1
      deviceSecret uwMTmVAMnxB****
      region cn-shanghai The ID of the region in which your device resides. For information about the format of region IDs, see Region.
      iotInstanceId iot-2w**** The ID of the instance to which the device belongs.

      You can view the instance ID on the Overview page in the IoT Platform console.

      • If the instance ID is displayed, you must specify this parameter.
      • If no Overview page or instance ID is displayed in the IoT Platform console, specify an empty string (iotInstanceId = "") for the parameter.
    • Configure the parameters to initialize the connection, including the MQTT connection parameters, device parameters, and TSL model parameters.
      LinkKitInitParams params = new LinkKitInitParams();
      // Configure the MQTT connection parameters. Link SDK uses the MQTT protocol. 
      IoTMqttClientConfig config = new IoTMqttClientConfig();
      config.productKey = productKey;
      config.deviceName = deviceName;
      config.deviceSecret = deviceSecret;
      config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
      // Configure the device parameters. 
      DeviceInfo deviceInfo = new DeviceInfo();
      deviceInfo.productKey = productKey;
      deviceInfo.deviceName = deviceName;
      deviceInfo.deviceSecret = deviceSecret;
      // Specify the initial status of the device. 
      Map<String, ValueWrapper> propertyValues = new HashMap<String, ValueWrapper>();
      
      params.mqttClientConfig = config;
      params.deviceInfo = deviceInfo;
      params.propertyValues = propertyValues;

      You must configure the parameters that are described in the following table based on your business requirements.

      Parameter Example Description
      config.channelHost config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883"; The endpoint that is used by the MQTT device to connect to the IoT Platform instance.
      • Public instances of the old version: config.channelHost = productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
      • Public instances of the old version and Enterprise Edition instances: config.channelHost = iotInstanceId + ".mqtt.iothub.aliyuncs.com:1883";
    • Initialize the connection.
      // Initialize the connection and configure the callback function that is used after the initialization succeeds. 
      LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
           @Override
           public void onError(AError aError) {
               System.out.println("Init error:" + aError);
           }
      
           // Implement the callback function. 
           @Override
           public void onInitDone(InitResult initResult) {
               System.out.println("Init done:" + initResult);
           }
       });
    • Send a message from the device.

      After the device is connected to IoT Platform, you can use the device to send a message to the custom topic. Replace the input of the onInitDone function with the following content:

      @Override
       public void onInitDone(InitResult initResult) {
           // Specify the topic to which the message is published and the message content. 
           MqttPublishRequest request = new MqttPublishRequest();
           request.topic = "/" + productKey + "/" + deviceName + "/user/devmsg";
           request.qos = 0;
           request.payloadObj = "{\"temperature\":35.0, \"time\":\"sometime\"}";
           // Publish the message and configure the callback functions that are used after the message is published. 
           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());
               }
           });
       }

      You must configure the parameters that are described in the following table based on your business requirements.

      Parameter Example Description
      request.topic "/" + productKey + "/" + deviceName + "/user/devmsg" The custom topic on which the device has the Publish permission.
      request.payloadObj "{\"temperature\":35.0, \"time\":\"sometime\"}" The content of the message.

      The server receives the following message:

      Message
      {payload={"temperature":35.0, "time":"sometime"},
      topic='/a1uzcH0****/device1/user/devmsg',
      messageId='1131755639450642944',
      qos=0,
      generateTime=1558666546105}

Configure the server to send a message to the device

The following figure shows how the server sends a message to the device.

Communication based on custom topics
  • Configure the device SDK to subscribe to a custom topic.

    For information about how to configure the parameters to authenticate the device and initialize the connection, see the sample code in the Configure the device to send a message to the server section.

    You must configure the device to subscribe to the custom topic.

    The following sample code provides an example on how to configure the device to subscribe to a topic:

    // Implement the callback function. 
    @Override
    public void onInitDone(InitResult initResult) {
        // Specify the topic to which the device subscribes. 
        MqttSubscribeRequest request = new MqttSubscribeRequest();
        request.topic = "/" + productKey + "/" + deviceName + "/user/cloudmsg";
        request.isSubscribe = true;
        // Send a subscription request and configure the callback functions that are invoked after the subscription succeeds or fails. 
        LinkKit.getInstance().subscribe(request, new IConnectSubscribeListener() {
            @Override
            public void onSuccess() {
                System.out.println("");
            }
    
            @Override
            public void onFailure(AError aError) {
    
            }
        });
    
        // Configure a listener for downstream messages. 
        IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
            // Configure the callback function that is used after the downstream messages are received. 
            @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);
    }

    You must set the request.topic parameter to a custom topic on which the device has the Subscribe permission.

  • Configure IoT Platform SDK to call the Pub operation to publish a message. For more information about the parameters, see Pub. For more information about how to configure the SDK, see Use IoT Platform SDK for Java.
    • Configure the parameters to authenticate the device.
       String regionId = "cn-shanghai";
       String accessKey = "LTAI4GFGQvKuqHJhFaj****";
       String accessSecret = "iMS8ZhCDdfJbCMeA005sieKe****";
       final String productKey = "a1uzcH0****";
       final String deviceName = "device1";
       final String iotInstanceId = "iot-2w****";

      You must configure the parameters that are described in the following table based on your business requirements.

      Parameter Example Description
      accessKey LTAI4GFGQvKuqHJhFaj**** The AccessKey ID and AccessKey secret of your Alibaba Cloud account.

      Log on to the IoT Platform console, move the pointer over the profile picture, and then click AccessKey Management to obtain the AccessKey ID and AccessKey secret.

      Note If you use a RAM user, you must attach the AliyunIOTFullAccess permission policy to the RAM user. The policy allows the RAM user to manage IoT Platform resources. Otherwise, the connection to IoT Platform fails. For more information about how to grant permissions to a RAM user, see RAM user access.
      accessSecret iMS8ZhCDdfJbCMeA005sieKe****
      productKey a1uzcH0**** The information about the device certificate. You can view the value of this parameter on the Device Details page in the IoT Platform console.For more information, see View detailed information about a device.
      deviceName device1
      region cn-shanghai The ID of the region in which your device resides. For information about the format of region IDs, see Region.
      iotInstanceId iot-2w**** The ID of the instance to which the device belongs.

      You can view the instance ID on the Overview page in the IoT Platform console.

      • If the instance ID is displayed, you must specify this parameter.
      • If no Overview page or instance ID is displayed in the IoT Platform console, specify an empty string (iotInstanceId = "") for the parameter.
    • Configure the connection parameters.
      // Configure the parameters of the client. 
      DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKey, accessSecret);
      IAcsClient client = new DefaultAcsClient(profile);
    • Configure the parameters that are used to publish a message.
      PubRequest request = new PubRequest();
      request.setIotInstanceId(iotInstanceId);
      request.setQos(0);
      // Specify the topic to which the message is published. 
      request.setTopicFullName("/" + productKey + "/" + deviceName + "/user/cloudmsg");
      request.setProductKey(productKey);
      // Configure the MessageContent parameter. The message content must be encoded in Base64. Otherwise, the message content is displayed as garbled characters. 
      request.setMessageContent(Base64.encode("{\"accuracy\":0.001,\"time\":now}"));

      When you call this operation, you must configure the parameters based on your business requirements. For more information, see Pub.

    • Publish the message.
      try {
           PubResponse response = client.getAcsResponse(request);
           System.out.println("pub success?:" + response.getSuccess());
       } catch (Exception e) {
           System.out.println(e);
       }
      The device receives the following message:
      msg = [{"accuracy":0.001,"time":now}]

Appendix: Sample code

Notice You must modify the code and specify parameters based on your business requirements.

You can click PubSubDemo to download the demo file. The demo file includes demos of IoT Platform SDK and device SDK.

For information about how to connect an AMQP client to IoT Platform, see the following topics: