IoT Platform allows you to create custom topic categories for products. When you configure your devices, you can specify the devices to send messages to custom topics. Your server can use the Advanced Message Queuing Protocol (AMQP) SDK to obtain messages from custom topics and can call the Pub operation to publish messages to custom topics to send commands to the device. Communication based on custom topics does not use the Thing Specification Language (TSL) model of the product. In this case, you can define the data structure for messages in custom topics.

Background information

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 the precision setting command to the thermometer.

Communication based on custom topics

Prepare the development environment

In this example, both devices and IoT Platform use SDKs for Java. You need to prepare the Java development environment first. You can download Java from the Java official website and install the Java development environment.

Create a product and a device

  1. Log on to the IoT Platform console.
  2. On the Overview page, find the instance and click the instance name to go to the Instance Details page.
    Notice Enterprise Edition instances are available only in the China (shanghai) and Japan (Tokyo) region. If your IoT Platform is not activated in the China (shanghai) or Japan (Tokyo) region, 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, you can obtain the value of 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 two topic categories are required:

    • /a1uzcH0****/${deviceName}/user/devmsg: Set the value of the Device Operation Authorizations parameter to Publish. Devices can send messages to this topic.
    • /a1uzcH0****/${deviceName}/user/cloudmsg: Set the value of 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 value of the Message Type parameter to Device Upstream Notification and select the default consumer group as the consumer group.
    Device Upstream Notification indicates messages that are reported by devices, including messages in custom topics and TSL messages. For information about how to configure AMQP subscription, see Configure an AMQP server-side subscription.
  8. In the left-side navigation pane, click Devices. Then, create a device named device1 to 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 the device to implement the process.

  • Configure your AMQP client to connect to IoT Platform and 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.
    • Specify information about the device certificate.
      final String productKey = "a1uzcH0****";
      final String deviceName = "device1";
      final String deviceSecret = "uwMTmVAMnxB***";
      final String region = "cn-shanghai";
    • Configure the parameters to initialize the connection, including the parameters for Message Queuing Telemetry Transport (MQTT) connection, parameters for device authentication, and TSL model parameters. The following sample code shows how to configure the parameters to connect a device to a public instance of IoT Platform.
      LinkKitInitParams params = new LinkKitInitParams();
      // Configure the parameters for MQTT connection. Link SDK uses MQTT as the underlying 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 parameters for device authentication. 
      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;
    • 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 send a message to the specified 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 specify 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());
               }
           });
       }

      After you send 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}

    In practice, you must configure the parameters based on the actual information.

    Parameter Sample value Description
    productKey a1uzcH0****

    The device authentication information. For more information, see Step 8 that is described in the Create a product and a device section.

    deviceName device1
    deviceSecret uwMTmVAMnxB***
    region cn-shanghai The ID of the region where your IoT Platform instance is deployed. For information about region IDs, see Regions and zones.
    channelHost iot-o***.mqtt.iothub.aliyuncs.com:1883 The connection address of the device. For more information, see View the endpoint of an instance.
    Notice If the address that you obtained does not contain the port number, add the port number 1883 to the address.
    request.topic "/" + productKey + "/" + deviceName + "/user/devmsg" The custom topic that you want to use. You must specify a topic to which devices can publish messages.
    request.payloadObj "{\"temperature\":35.0, \"time\":\"sometime\"}" The content of the message that you want to send.

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 specify 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 example shows how to configure the device SDK 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 used 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) {
    
            }
        });
    
        // Specify the listener that is used to listen to downstream messages. 
        IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
            // Configure the callback function that are used after the device receives downstream messages. 
            @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 specify the value of the request.topic parameter to the name of a custom topic that has the Subscribe permission.

  • Configure IoT Platform SDK to call the Pub operation to publish a message. For information about the request parameters, see Pub. For information about how to configure the SDK, see Use IoT Platform SDK for Java. The following sample code shows how to publish messages to devices in a public instance of IoT Platform.
    • Specify information about the device certificate.
       String regionId = "***";
       String accessKey = "***";
       String accessSecret = "***";
       final String productKey = "***";
    • Configure the connection parameters.
      // Configure 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.setQos(0);
      // Specify the topic to which you want to publish the message. 
      request.setTopicFullName("/" + productKey + "/" + deviceName + "/user/cloudmsg");
      request.setProductKey(productKey);
      // Specify the message content. The message content must be encoded in Base64. Otherwise, the message content appears as garbled text. 
      request.setMessageContent(Base64.encode("{\"accuracy\":0.001,\"time\":now}"));
    • Publish the message.
      try {
           PubResponse response = client.getAcsResponse(request);
           System.out.println("pub success?:" + response.getSuccess());
       } catch (Exception e) {
           System.out.println(e);
       }
      After the message is published, the device receives the following message:
      msg = [{"accuracy":0.001,"time":now}]

Appendix: Sample code

Note In practice, you must configure the parameters based on the actual information.

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

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