MQTT Essentials Part 4: MQTT Publish, Subscribe & Unsubscribe
Welcome to the fourth part of the MQTT Essentials, a blog series about the core features and concepts in the MQTT protocol. In this post, we’ll focus on publish, subscribe and unsubscribe in MQTT. In contrast to the second part, which was about publish/subscribe basics, this post will explain the specifics of publish and subscribe in the MQTT protocol. If you haven’t read part 2 about the basics of the publish/subscribe pattern, we strongly encourage you to read it first.
Last week we looked at establishing a connection between MQTT client and broker. So this week’s post ties on to this and we’ll talk about sending and receiving messages.
After a MQTT client is connected to a broker, it can publish messages. MQTT has a topic-based filtering of the messages on the broker (check part 2 for more details on that), so each message must contain a topic, which will be used by the broker to forward the message to interested clients. Each message typically has a payload which contains the actual data to transmit in byte format. MQTT is data-agnostic and it totally depends on the use case how the payload is structured. It’s completely up to the sender if it wants to send binary data, textual data or even full-fledged XML or JSON. A MQTT publish message also has some more attributes, which we’re going discuss in detail:
A simple string, which is hierarchically structured with forward slashes as delimiters. An example would be “myhome/livingroom/temperature” or “Germany/Munich/Octoberfest/people”. More details about topics can be found in part 5 of the MQTT Essentials.
A Quality of Service Level (QoS) for this message. The level (0,1 or 2) determines the guarantee of a message reaching the other end (client or broker). More details about QoS can be found in part 6 of the MQTT Essentials.
This flag determines if the message will be saved by the broker for the specified topic as last known good value. New clients that subscribe to that topic will receive the last retained message on that topic instantly after subscribing. More on retained messages and best practices in one of the next posts.
This is the actual content of the message. MQTT is totally data-agnostic, it’s possible to send images, texts in any encoding, encrypted data and virtually every data in binary.
The packet identifier is a unique identifier between client and broker to identify a message in a message flow. This is only relevant for QoS greater than zero. Setting this MQTT internal identifier is the responsibility of the client library and/or the broker.
The duplicate flag indicates, that this message is a duplicate and is resent because the other end didn’t acknowledge the original message. This is only relevant for QoS greater than 0 and more details are in part 6, which is about QoS levels. This resend/duplicate mechanism is typically handled by the MQTT client library or the broker as an implementation detail.
So when a client sends a publish to a MQTT broker, the broker will read the publish, acknowledge the publish if needed (according to the QoS Level) and then process it. Processing includes determining which clients have subscribed on that topic and then sending out the message to the selected clients which subscribe to that topic.
The client, who initially published the message is only concerned about delivering the publish message to the broker. From there on it is the responsibility of the broker to deliver the message to all subscribers. The publishing client doesn’t get any feedback, if someone was interested in this published message and how many clients received the message by the broker.
Publishing messages doesn’t make sense if no one ever receives the message, or, in other words, if there are no clients subscribing to any topic. A client needs to send a SUBSCRIBE message to the MQTT broker in order to receive relevant messages. A subscribe message is pretty simple, it just contains a unique packet identifier and a list of subscriptions.
The packet identifier is a unique identifier between client and broker to identify a message in a message flow. Setting this MQTT internal identifier is the responsibility of the client library and/or the broker.
List of Subscriptions
A SUBSCRIBE message can contain an arbitrary number of subscriptions for a client. Each subscription is a pair of a topic topic and QoS level. The topic in the subscribe message can also contain wildcards, which makes it possible to subscribe to certain topic patterns. If there are overlapping subscriptions for one client, the highest QoS level for that topic wins and will be used by the broker for delivering the message.
Each subscription will be confirmed by the broker through sending an acknowledgment to the client in form of the SUBACK message. This message contains the same packet identifier as the original Subscribe message (in order to identify the message) and a list of return codes.
The packet identifier is a unique identifier used to identify a message. It is the same as in the SUBSCRIBE message.
The broker sends one return code for each topic/QoS-pair it received in the SUBSCRIBE message. So if the SUBSCRIBE message had 5 subscriptions, there will be 5 return codes to acknowledge each topic with the QoS level granted by the broker. If the subscription was prohibited by the broker (e.g. if the client was not allowed to subscribe to this topic due to insufficient permission or if the topic was malformed), the broker will respond with a failure return code for that specific topic.
|Return Code||Return Code Response|
|0||Success – Maximum QoS 0|
|1||Success – Maximum QoS 1|
|2||Success – Maximum QoS 2|
After a client successfully sent the SUBSCRIBE message and received the SUBACK message, it will receive every published message matching the topic of the subscription.
The counterpart of the SUBSCRIBE message is the UNSUBSCRIBE message which deletes existing subscriptions of a client on the broker. The UNSUBSCRIBE message is similar to the SUBSCRIBE message and also has a packet identifier and a list of topics.
The packet identifier is a unique identifier used to identify a message. The acknowledgement of an UNSUBSCRIBE message will contain the same identifier.
List of Topic
The list of topics contains an arbitrary number of topics, the client wishes to unsubscribe from. It is only necessary to send the topic as string (without QoS), the topic will be unsubscribed regardless of the QoS level it was initially subscribed with.
The broker will acknowledge the request to unsubscribe with the UNSUBACK message. This message only contains a packet identifier.
The packet identifier is a unique identifier used to identify a message. It is the same as in the UNSUBSCRIBE message.
After receiving the UNSUBACK from the broker, the client can assume the subscriptions in the UNSUBSCRIBE message are deleted.
So that’s the end of part four in our MQTT Essentials series. We hope you enjoyed it. In the next post we will dig deeper into the usage of MQTT topics. We’ll explain the basics as well as the usage of wildcards and a lot of practical examples.
Have a great week and we’ll hope to see you on the next MQTT Monday!
If you still haven’t signed up for our newsletter in order to get each new post delivered directly to your inbox, you can do so below. If you prefer RSS, you can subscribe to our RSS feed here.