Testing message delivery
When sending a message, you may need to verify that it was delivered. Messages may fail to reach the MQTT server, e.g., if a message is sent:
- To a non-existing device topic.
- From a client with writes to the specified topic disabled.
- From a client that is not authenticated in the system.
The IoT network structure assumes that MQTT clients connect to the MQTT server. It accepts messages sent by publishers and forwards them to subscribers. MQTT does not support notifications that the message has been delivered to subscriber. You can only get a confirmation that a message has been delivered to the MQTT server.
To ascertain that the MQTT server has received the message, specify additional debugging parameters in the send message command. As a result, you will get a detailed command output.
To test the Yandex IoT Core service, use both messaging and device subscription at the same time. If you subscribe a registry to a device topic and send a message to this topic, the registry will receive the message.
In the example below, a device with a light intensity sensor sends the light intensity value of 150
to a permanent device topic. Client authentication is performed through X.509 certificates. The CLI and Mosquitto
Getting started
-
If you do not have the Yandex Cloud command line interface yet, install and initialize it.
The folder specified in the CLI profile is used by default. You can specify a different folder using the
--folder-name
or--folder-id
parameter. -
(Optional) Download and install Mosquitto
if you want to use it for sending messages and subscribing to the device instead of the CLI.To connect to the MQTT server via Mosquitto, use the following parameters:
- Certificate from the certificate authority
. - Server address:
mqtt.cloud.yandex.net
. - Server port:
8883
. - Protocol:
TLSv1.2
.
- Certificate from the certificate authority
Send a message with debugging parameters
When sending messages, add the following flags to the command:
-
--qos 1
for the CLI or-q 1
for Mosquitto: Quality of service (QoS) levelQoS 1: At least once
. This level guarantees that a message is delivered to a client at least once.With this QoS level, the MQTT server sends a PUBACK packet
to the publisher. This is how the server confirms that it has received a message from the publisher. -
--debug
for the CLI and Mosquitto: Command debugging. Outputs the debug log when executing the command and helps both diagnose an issue and find out whether the PUBACK packet has been received.
Example of sending a message:
yc iot mqtt publish \
--cert sensor-cert.pem \
--key sensor-key.pem \
--topic '$devices/b91qprkvbks9********/state' \
--message '150' \
--qos 1 \
--debug
Where:
--cert
: Path to the public part of the certificate of the device with the sensor.--key
: Path to the private part of the certificate of the device with the sensor.--topic
: Permanent topic of the device with the sensor.--message
: Message text.--qos
: Quality of service (QoS) level.--debug
: Debug log output.
mosquitto_pub -h mqtt.cloud.yandex.net \
-p 8883 \
--cafile rootCA.crt \
--cert sensor-cert.pem \
--key sensor-key.pem \
-t '$devices/b91qprkvbks9********/state' \
-m '150' \
-q 1 \
--debug
Where:
-h
: MQTT server address.-p
: MQTT server port.--cafile
: Path to the certificate from the certificate authority.--cert
: Path to the public part of the certificate of the device with the sensor.--key
: Path to the private part of the certificate of the device with the sensor.-t
: Permanent topic of the device with the sensor.-m
: Message text.-q
: Quality of service level.--debug
: Debug log output.
Result example:
...
15:02:27.030752 [client] enter Publish
15:02:27.030797 [client] sending publish message, topic:$devices/b91qprkvbks9********/state
15:02:27.030923 [net] obound wrote msg, id:1
15:02:27.030947 [net] outgoing waiting for an outbound message
15:02:27.261271 [net] Received Message
15:02:27.261530 [net] logic got msg on ibound
15:02:27.261587 [store] memorystore del: message1was deleted
15:02:27.261624 [net] received puback, id:1
15:02:27.261674 [net] logic waiting for msg on ibound
15:02:27.261719 [client] disconnecting
...
Client null sending CONNECT
Client null received CONNACK (0)
Client null sending PUBLISH (d0, q1, r0, m1, '$devices/b91qprkvbks9********/state', ... (6 bytes))
Client null received PUBACK (Mid: 1, RC:0)
Client null sending DISCONNECT
This result indicates that the client has received the PUBACK packet. This is a confirmation from the MQTT server that it has received the message.
Use two clients to work with the same topic
To make sure a sent message has been delivered, subscribe your registry to a device topic. The MQTT server receives messages from topics and forwards them to subscribers. Therefore, if a subscriber has received a message, the MQTT has received it, too.
To use two clients to work with the same topic:
- Subscribe a registry to a device's permanent topic
- Send a message to the device's permanent topic
- Make sure the registry has received the message from the device
Subscribe your registry to the device's permanent topic
Run this command:
yc iot mqtt subscribe \
--cert registry-cert.pem \
--key registry-key.pem \
--topic '$devices/b91qprkvbks9********/state' \
--qos 1 \
--debug
Where:
--cert
: Path to the public part of the registry.--key
: Path to the private part of the registry certificate.--topic
: Permanent topic of the device with the sensor.--qos
: Quality of service (QoS) level.--debug
: Debug log output.
mosquitto_sub -h mqtt.cloud.yandex.net \
-p 8883 \
--cafile rootCA.crt \
--cert registry-cert.pem \
--key registry-key.pem \
-t '$devices/b91qprkvbks9********/state' \
-q 1 \
--debug
Where:
-h
: MQTT server address.-p
: MQTT server port.--cafile
: Path to the certificate from the certificate authority.--cert
: Path to the public part of the registry.--key
: Path to the private part of the registry certificate.-t
: Permanent topic of the device with the sensor.-q
: Quality of service level.--debug
: Debug log output.
Result example:
...
15:46:20.619042 [client] enter Subscribe
15:46:20.619133 [client] SUBSCRIBE: dup: false qos: 1 retain: false rLength: 0 MessageID: 0 topics: [$devices/b91qprkvbks9********/state]
15:46:20.619170 [client] exit Subscribe
15:46:20.619214 [net] obound priority msg to write, type*packets.SubscribePacket
15:46:20.619385 [net] outgoing waiting for an outbound message
15:46:20.699795 [net] Received Message
15:46:20.699959 [net] logic got msg on ibound
15:46:20.700002 [store] memorystore del: message1not found
15:46:20.700027 [net] received suback, id:1
15:46:20.700055 [net] granted qoss[128]
15:46:20.700092 [net] logic waiting for msg on ibound
Client null sending CONNECT
Client null received CONNACK (0)
Client null sending SUBSCRIBE (Mid: 1, Topic: $devices/b91qprkvbks9********/state, QoS: 1, Options: 0x00)
Client null received SUBACK
Subscribed (mid: 1): 1
This result indicates that the client has received the SUBACK packet
Once the result is output, the command is not terminated. The MQTT client pings the topic on a regular basis waiting for a new message:
15:47:45.554570 [pinger] ping check5
15:47:50.554346 [pinger] ping check10
15:47:55.554149 [pinger] ping check15
Client null sending PINGREQ
Client null received PINGRESP
Send a message to the device's permanent topic
Open a new terminal window and run this command:
yc iot mqtt publish \
--cert sensor-cert.pem \
--key sensor-key.pem \
--topic '$devices/b91qprkvbks9********/state' \
--message '150' \
--qos 1 \
--debug
Where:
--cert
: Path to the public part of the certificate of the device with the sensor.--key
: Path to the private part of the certificate of the device with the sensor.--topic
: Permanent topic of the device with the sensor.--message
: Message text.--qos
: Quality of service (QoS) level.--debug
: Debug log output.
mosquitto_pub -h mqtt.cloud.yandex.net \
-p 8883 \
--cafile rootCA.crt \
--cert sensor-cert.pem \
--key sensor-key.pem \
-t '$devices/b91qprkvbks9********/state' \
-m '150' \
-q 1 \
--debug
Where:
-h
: MQTT server address.-p
: MQTT server port.--cafile
: Path to the certificate from the certificate authority.--cert
: Path to the public part of the certificate of the device with the sensor.--key
: Path to the private part of the certificate of the device with the sensor.-t
: Permanent topic of the device with the sensor.-m
: Message text.-q
: Quality of service level.--debug
: Debug log output.
Result example:
...
15:02:27.030752 [client] enter Publish
15:02:27.030797 [client] sending publish message, topic:$devices/b91qprkvbks9********/state
15:02:27.030923 [net] obound wrote msg, id:1
15:02:27.030947 [net] outgoing waiting for an outbound message
15:02:27.261271 [net] Received Message
15:02:27.261530 [net] logic got msg on ibound
15:02:27.261587 [store] memorystore del: message1was deleted
15:02:27.261624 [net] received puback, id:1
15:02:27.261674 [net] logic waiting for msg on ibound
15:02:27.261719 [client] disconnecting
...
Client null sending CONNECT
Client null received CONNACK (0)
Client null sending PUBLISH (d0, q1, r0, m1, '$devices/b91qprkvbks9********/state', ... (3 bytes))
Client null received PUBACK (Mid: 1, RC:0)
Client null sending DISCONNECT
Make sure the registry has received the message from the device
If the message is delivered, the subscribe to device command outputs the result. Here is an example:
17:23:26.346405 [net] Received Message
17:23:26.346493 [net] logic got msg on ibound
17:23:26.346518 [net] received publish, msgId:4
17:23:26.346530 [net] putting msg on onPubChan
17:23:26.346580 [net] done putting msg on incomingPubChan
17:23:26.346590 [net] logic waiting for msg on ibound
17:23:26.346591 [net] putting puback msg on obound
17:23:26.346632 [store] memorystore del: message4was deleted
17:23:26.346646 [net] done putting puback msg on obound
150
17:23:26.346656 [net] obound priority msg to write, type*packets.PubackPacket
17:23:26.346761 [net] outgoing waiting for an outbound message
Client null received PUBLISH (d0, q1, r0, m3, '$devices/b91qprkvbks9********/state', ... (3 bytes))
Client null sending PUBACK (m3, rc0)
150
The result contains 150, which is the message that was sent.