Publishing messages
We will use the mosquitto_pub
command-line utility included in Mosquitto to generate a simple MQTT client that publishes a message to a topic. Open a Terminal in macOS or Linux, or a Command Prompt in Windows, go to the directory in which Mosquitto is installed and run the following command:
mosquitto_pub -V mqttv311 -t sensors/drone01/altitude -m "10 f" -d
The previous command will create an MQTT client that will establish a connection with the local MQTT server and then will make the client publish a message to the topic specified after the -t
option: sensors/drone01/altitude
. We specify the payload for the message after the -m
option: "10 f"
. We specify the version of the MQTT protocol that we want to use when the client establishes the connection with -V mqttv311
. This way, we indicate the MQTT server that we want to use MQTT version 3.1.1. We specify the -d
option to enable debug messages that will allow us to understand what happens under the hoods. We will analyze additional options for the connection and the publication later.
The Terminal or Command Prompt window will display debug messages similar to the following lines. Take into account that the generated ClientId
will be different from the one shown after Client
:mosqpub/5303-Gastons-Ma
. After publishing the message, the client disconnects.
Client mosqpub/5308-Gastons-Ma sending CONNECT Client mosqpub/5308-Gastons-Ma received CONNACK Client mosqpub/5308-Gastons-Ma sending PUBLISH (d0, q0, r0, m1, 'drones/altitude', ... (5 bytes)) Client mosqpub/5308-Gastons-Ma sending DISCONNECT
Now, we will use the MQTT.fx GUI utility to generate another MQTT client that publishes another message to the same topic, sensors/drone01/altitude
. Follow the next steps:
- Go to the MQTT.fx window in which you established a connection and subscribed to a topic.
- Click Publish and enter
sensors/drone01/altitude
in the dropdown at the left-hand side of the Publish button. - Enter the following text in the textbox below the Publish button:
20 f
, as shown in the following screenshot: - Then, click the Publish button. MQTT.fx will publish the entered text to the specified topic.
In case you don't want to work with the MQTT.fx utility, you can run another mosquitto_pub
command to generate another MQTT client that publishes a message to the topic. You just need to open another Terminal in macOS or Linux, or another Command Prompt in Windows, go to the directory in which Mosquitto is installed and run the following command.
mosquitto_pub -V mqttv311 -t sensors/drone01/altitude -m "20 f"
Now, go back to the Terminal or Command Prompt window in which you executed the mosquitto_sub
command and subscribed to the sensors/drone01/atitude
topic. You will see lines similar to the following ones:
Client mosqsub/5532-Gastons-Ma received PUBLISH (d0, q0, r0, m0, 'sensors/drone01/altitude', ... (4 bytes)) 10 f Client mosqsub/5532-Gastons-Ma received PUBLISH (d0, q0, r0, m0, 'sensors/drone01/altitude', ... (4 bytes)) 20 f
If we clean up the debug messages that start with the Client
prefix, we will see just the next two lines. These lines show the payloads for the two messages that we received as a result of our subscription to the sensors/drone01/altitude
topic.
10 f 20 f
Go to the MQTT.fx window and click Subscribe. You will see 2 at the right-hand side of the title for the topic filter used to subscribe in the panel located at the left-hand side of the window. MQTT.fx is telling you that you have received two messages in the sensors/drone01/altitude
topic. Click on this panel and MQTT.fx will display all the received messages at the right-hand side of the panel. MQTT.fx will display a number at the right-hand side of each message to specify the message number since we started the subscription to the topic filter. Click on each message and MQTT.fx will display the QoS level for the message (0), the date and time that it was received and the payload for the message in the default plain string format. The following picture shows the payload for the second message that has been received by the subscriber generated by MQTT.fx.
We created two publishers and each of them published a message to the same topic: sensors/drone01/altitude
. The two subscribers for this topic received both messages. Now, we will understand what happens under the hoods when a client publishes a message to a topic.
The MQTT client that has already established a connection sends a PUBLISH
packet to the MQTT server with a header that includes the following fields and flags. We want to understand the meaning of these fields and flags because we will be able to specify some of their values when we work with MQTT tools and MQTT client libraries.
PacketId
: If the QoS level is equal to 0, the value for this field will be 0 or it won't be present. In case the QoS level is equal to 1 or 2, the packet identifier will have a number value to identify the packet and make it possible to identify the responses related to this packet.Dup
: If the QoS level is equal to 0, the value for this field will be 0. In case the QoS level is equal to 1 or 2, the MQTT client library or the MQTT server can resend a message that was previously published by the client when the subscribers haven't ackowledged the first message. Whenever there is an attempt to resend a message that has already been published, the value for theDup
flag must be1
ortrue
.QoS
: Specifies the QoS level for the message. We will dive deep on the quality of service level for the messages and their relationship with many other flags later. So far, we have been working with QoS level0
.Retain
:If the value for this flag is set to1
ortrue
, the MQTT server will store the message with its specified QoS level. Whenever new MQTT clients subscribers to a topic filter that matches the topic for the stored or retained message, the last stored message for this topic will be sent to the new subscriber. If the value for this flag is set to0
orfalse
, the MQTT server won't store the message and won't replace a retained message with the same topic in case there is one message retained for this topic.TopicName
: A string with the topic name to which the message must be published. Topic names have a hierarchy structure where slashes (/
) are used as delimiters. In our examples, the value forTopicName
was"sensors/drone01/altitude"
. We will analyze best practices for topic names later.
Tip
The payload contains the actual message that the MQTT client wants the MQTT server to publish. MQTT is data agnostic, and therefore, we can send any binary data and we don't have restrictions such as those imposed by JSON or XML. Of course, we can use these or others to organize the payloads if we wish. In our examples, we sent a string that included a number that represented the altitude followed by a space and an "f"
that indicates the unit of measure is feet
.
The MQTT server will read a valid PUBLISH
packet and it will respond with a packet only for QoS levels greater than 0
. In case the QoS level is 0
, the MQTT will not respond. The MQTT server will determine all the subscribers whose subscribed topic matches the topic name specified for the message and the server will publish the message to these clients.
The following diagram shows the interaction between an MQTT client and an MQTT server to publish a message with a QoS level of 0
.
The other QoS levels have a different flow with additional interaction between the publisher and the MQTT server and increased overheads that we will analyze later.