Message Delivery
Overview
Message delivery does not rely on product models. The platform provides one-way notifications for devices and caches messages. It delivers messages from the cloud to devices in asynchronous mode (without waiting for responses from devices). If a device is offline, data is sent after the device is online. The maximum cache duration is 24 hours. By default, the platform stores a maximum of 20 messages for each device. If the number of messages exceeds 20, subsequent messages will replace the earliest messages. In addition, messages can be delivered in the format of custom topics.
Message Delivery Topic Type |
Description |
---|---|
System topic |
The platform predefines topics for communications with devices. For details of the topic list and functions, see Topics. |
Custom topic |
You can customize topics for device-platform communications. Types of custom topics:
|
Scenarios
- The data format needs to be customized and does not rely on the product model.
Constraints
- Max. size of a single message: 256 KB.
- Up to 20 messages can be cached for a single device.
- Max. length of a custom MQTT topic: 128 bytes.
- Max. cache duration (configurable): 24 hours.
Quality of Service
- IoTDA supports MQTT QoS 0 and QoS 1, but does not support QoS 2.
- If the QoS of a topic is 0, the message is delivered only once without waiting for the device to return an ACK message. If the QoS of a topic is 1, the message delivery is successful only after the device returns an ACK message.
- Devices subscribe to the system topic whose QoS is 0 by default. If the downstream system topic whose QoS is 1 is required, devices need to be configured to subscribe to the topic.
- If a device needs to subscribe to a custom topic that does not start with $oc and the QoS is 1, submit a service ticket.
- If the QoS of the subscribed topic is 1 and the platform does not receive an ACK message from the device, the platform resends the message every 2 seconds for three times by default.
If the device still does not return an acknowledgment response and the message is still cached, the platform resends the message when the device goes online again or subscribes to a topic. By default, the platform resends the message every 10 seconds for five times.
In addition, the mechanism of resending every 2 seconds is triggered. Therefore, the device may receive duplicate messages. It is recommended that devices have deduplication mechanisms.
Delayed Message Delivery
Message delivery is a mode in which the platform directly delivers messages to devices. When a device is offline, the platform caches messages to be delivered until the device goes online.
- An application or the third-party platform calls the API for delivering a message to a device to send a message to IoTDA. Example message:
POST https://{Endpoint}/v5/iot/{project_id}/devices/{device_id}/messages Content-Type: application/json X-Auth-Token: ******** { "message_id": "99b32da9-cd17-4cdf-a286-f6e849cbc364", "name": "messageName", "message": "HelloWorld" }
- The platform sends a 201 Created message carrying the message status PENDING to the application.
- The platform pushes the message result to the application through the API for pushing a device message status change notification. If the device is offline, the message status is PENDING.
Topic: $oc/devices/{device_id}/sys/messages/down Data format: { "resource": "device.message.status", "event": "update", "notify_data": { "message_id": "string", "name": "string", "device_id": "string", "status": "PENDING", "timestamp": "string" } }
- The device goes online.
- The device subscribes to the non-system topic to receive messages. (Implicit subscription mode: Devices do not need to subscribe to downstream system topics.)
- The platform sends the message to the device according to the protocol specifications. Example message:
Topic: $oc/devices/{device_id}/sys/messages/down Data format: { "object_device_id": "{object_device_id}", "name": "name", "id": "id", "content": "hello" }
- The platform pushes the final result of the message to the application. The message status is DELIVERED. For details about the used APIs, see Push a Device Message Status Change Notification.
Topic: $oc/devices/{device_id}/sys/messages/down Data format: { "resource": "device.message.status", "event": "update", "notify_data": { "message_id": "string", "name": "string", "device_id": "string", "status": "DELIVERED", "timestamp": "string" } }
Introduction for QoS 1
The following uses an MQTT device as an example to describe how to use a system topic whose QoS is 1 to deliver messages to devices.
- The device goes online.
- Subscribe to a topic for the device and set QoS to 1.
Figure 3 Setting QoS to 1 for the subscribed topic
- An application or the third-party platform calls the API for delivering a message to a device to send a message to IoTDA. Example message:
POST https://{Endpoint}/v5/iot/{project_id}/devices/{device_id}/messages Content-Type: application/json X-Auth-Token: ******** { "message_id": "99b32da9-cd17-4cdf-a286-f6e849cbc364", "name": "messageName", "message": "HelloWorld" }
- The platform sends the message to the device according to the protocol specifications. An MQTT device needs to subscribe to the non-system topic to receive messages. (Implicit subscription mode: Devices do not need to subscribe to downstream system topics.) Example message:
Topic: $oc/devices/{device_id}/sys/messages/down Data format: { "object_device_id": "{object_device_id}", "name": "name", "id": "id", "content": "hello" }
- After delivering a message to the device, the platform returns a 201 Created message to the application. The message status is DELIVERED. Message delivery is an asynchronous operation. The platform can return the response without waiting for an ACK message from the device.
- If the IoT platform does not receive an ACK response from the device, it resends the message every 2 seconds for three times by default.
- The device goes online again or subscribes to a topic.
- If the device does not return an ACK response for the previous message and the message does not time out, the platform resends the message every 10 seconds for five times by default. This mechanism of resending every 2 seconds is triggered.
- The platform pushes the final result of the message to the application. The message status is DELIVERED or TIMEOUT. For details about the used APIs, see Push a Device Message Status Change Notification.
Topic: $oc/devices/{device_id}/sys/messages/down Data format: { "resource": "device.message.status", "event": "update", "notify_data": { "message_id": "string", "name": "string", "device_id": "string", "status": "DELIVERED", "timestamp": "string" } }
Message Delivery Status
The following figure shows the MQTT device message execution status and status change mechanism.
Status |
Description |
---|---|
PENDING |
If an MQTT device is offline, the platform caches the message. In this case, the task status is PENDING. |
TIMEOUT |
If the platform does not deliver the message in the pending status after one day, the task status changes to TIMEOUT. |
DELIVERED |
After the platform sends the message to the device, the task status changes to DELIVERED. |
FAILED |
If the platform fails to send a message to the device, the task status changes to FAILED. |
Example of Platform Message Delivery
To deliver messages from the cloud, create a delivery task on the console. The following uses an MQTT device as an example to describe how to cache and deliver messages on the IoTDA console.
- Access the IoTDA service page and click Access Console. Click the target instance card.
- In the navigation pane, choose Devices > All Devices. On the device list, click a device to access its details page.
- Click the Cloud Delivery tab. On the Message Delivery tab page, click Deliver Message. In the displayed dialog box, configure the content and the parameters for the command to deliver.
Figure 5 Message delivery - MQTT
- The delivery status is DELIVERED on the platform.
Figure 6 Querying results
Configure the Java SDK on the application side:
- Configure the Maven dependency. In this example, the development environment is JDK 1.8 or later. Download an SDK.
<dependency> <groupId>com.huaweicloud.sdk</groupId> <artifactId>huaweicloud-sdk-core</artifactId> <version>[3.0.40-rc, 3.2.0)</version> </dependency> <dependency> <groupId>com.huaweicloud.sdk</groupId> <artifactId>huaweicloud-sdk-iotda</artifactId> <version>[3.0.40-rc, 3.2.0)</version> </dependency>
- The following is an example of a message sent by the application to a single device:
public class MessageDistributionSolution { // REGION_ID: If CN East-Shanghai1 is used, enter cn-east-3. If CN North-Beijing4 is used, enter cn-north-4. If CN South-Guangzhou is used, enter cn-south-4. private static final String REGION_ID = "<YOUR REGION ID>"; // ENDPOINT: On the console, choose Overview and click Access Addresses to view the HTTPS application access address. private static final String ENDPOINT = "<YOUR ENDPOINT>"; // For the standard or enterprise edition, create a region object. public static final Region REGION_CN_NORTH_4 = new Region(REGION_ID, ENDPOINT); public static void main(String[] args) { String ak = "<YOUR AK>"; String sk = "<YOUR SK>"; String projectId = "<YOUR PROJECTID>"; // Create a credential. ICredential auth = new BasicCredentials().withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE) .withAk(ak) .withSk(sk) .withProjectId(projectId); // Create and initialize an IoTDAClient instance. IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth) // For the basic edition, select the region object in IoTDARegion. //.withRegion(IoTDARegion.CN_NORTH_4) // For the standard or enterprise edition, create a region object. .withRegion(REGION_CN_NORTH_4).build(); // Instantiate a request object. CreateMessageRequest request = new CreateMessageRequest(); request.withDeviceId("<YOUR DEVICE_ID>"); DeviceMessageRequest body = new DeviceMessageRequest(); body.withMessage("<YOUR DEVICE MESSAGE>"); request.withBody(body); try { CreateMessageResponse response = client.createMessage(request); System.out.println(response.toString()); } catch (ConnectionException e) { e.printStackTrace(); } catch (RequestTimeoutException e) { e.printStackTrace(); } catch (ServiceResponseException e) { e.printStackTrace(); System.out.println(e.getHttpStatusCode()); System.out.println(e.getRequestId()); System.out.println(e.getErrorCode()); System.out.println(e.getErrorMsg()); } } }
Table 3 Parameters Parameter
Description
ak
Access key ID (AK) of your Huawei Cloud account. You can create and check your AK/SK on the My Credentials > Access Keys page of the Huawei Cloud console. For details, see Access Keys.
sk
Secret access key (SK) of your Huawei Cloud account.
projectId
Project ID. For details on how to obtain a project ID, see Obtaining a Project ID.
IoTDARegion.CN_NORTH_4
Region where the platform to be accessed is located. The available regions of the platform have been defined in the SDK code IoTDARegion.java.
On the console, you can view the region name of the current service and the mapping between regions and endpoints. For details, see Platform Connection Information.
REGION_ID
If CN East-Shanghai1 is used, enter cn-east-3. If CN North-Beijing4 is used, enter cn-north-4. If CN South-Guangzhou is used, enter cn-south-4.
ENDPOINT
On the console, choose Overview and click Access Addresses to view the HTTPS application access address.
DEVICE_ID
Unique ID of the device that a message is delivered to. The value of this parameter is allocated by the platform during device registration. The value is a string of no more than 128 characters. Only letters, digits, underscores (_), and hyphens (-) are allowed.
In the example, JDK 1.8 or a later version is used. Download an SDK. Configure the Java SDK on the device:
- Configure the Maven dependency of the SDK on devices.
<dependency> <groupId>com.huaweicloud</groupId> <artifactId>iot-device-sdk-java</artifactId> <version>1.1.4</version> </dependency>
- Configure the SDK and device connection parameters on devices.
// Load the CA certificate of the IoT platform. For details about how to obtain the certificate, visit https://support.huaweicloud.com/intl/en-us/devg-iothub/iot_02_1004.html. URL resource = BroadcastMessageSample.class.getClassLoader().getResource("ca.jks"); File file = new File(resource.getPath()); // The format is ssl://Domain name:Port number. // To obtain the domain name, log in to the Huawei Cloud IoTDA console. In the navigation pane, choose Overview and click Access Details in the Instance Information area. Select the access domain name corresponding to port 8883. String serverUrl = "ssl://localhost:8883"; // Device ID created on the platform String deviceId = "deviceId"; // Secret corresponding to the device ID String deviceSecret = "secret"; // Create a device. IoTDevice device = new IoTDevice(serverUrl, deviceId, deviceSecret, file); if (device.init() != 0) { return; }
- Define the message delivery callback function.
client.setDeviceMessageListener(deviceMessage -> { log.info("the onDeviceMessage is {}", deviceMessage.toString()); });
Verify the setting:
- On the IoTDA console, click the target instance card. In the navigation pane, choose Devices > All Devices. On the displayed page, locate the target device, and click View in the Operation column to access its details page. Click the Message Trace tab, and click Start Trace.
Figure 7 Message tracing - Starting message tracing
- Run the SDK code on the application and deliver a message. The following is an example of the response from the platform.
Figure 8 Response indicating the delivery success of the application message
- The record can be checked on the Message Trace tab page.
Figure 9 Message tracing - Caching delivered messages
- Run the SDK code on the device. The following is an example of the log format when the device receives a message.
Figure 10 Device receiving messages
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot