MQTT in a Nutshell
— Part 3, Clean Session, QoS and Retained Message
Sometimes it is expected that an MQTT Broker stores the subscription and queues messages for a client when it is disconnected and delivers the messages when it is back online later. In the MQTT world, there are techniques like retained message, QoS level and clean session, they all have an effect on storing messages for clients. We will discuss them in this short article.
You have the choice to tell the broker if it should store the session information for you, when you are connection to it, by specifying the ‘clean_session’ flag in the CONNECT packet.
If a client connects only to publish messages, it doesn’t matter whether the broker remembers it or not. But if a client is connecting to subscribe, it is convenient, or necessary, to make the connection “persistent” by setting the ‘clean_session’ bit to 0 in the CONNECT packet. Then, the subscription information and undelivered messages will be stored for this client.
To connect with clean_session set to false, a client id must be used.
It is impossible to change the ‘clean_session’ setting when connected. To change it, you need to reconnect with new setting.
Not all messages of a “persistent” connection will be stored. The QoS level also has a effect on it.
MQTT protocol guarantees only the messages with QoS 1 or QoS 2 are assuredly delivered to the subscribers. For those with QoS 0, it tries send them once and does not guarantee for the delivery. Following this principle, only the QoS 1 and QoS 2 messages are stored when the subscriber is disconnected, even for a “persistent” connection.
To be noticed is that MQTT don’t use end-to-end QoS, which mean, the messages are only stored when they are published with QoS != 0 and subscribed with QoS != 0.
MQTT messages can be retained on the broker and be delivered to the subscriber when it connects, if you publish these messages with ‘retain’ bit set to 1.
It is a useful feature, only the word “retain” is sometimes confusing. It doesn’t retain all messages, not with the same topic. For each topic, only the last published message is retained, the earlier ones are replaced by their successor. Also, a message with retain flag set to 0 will NOT replace the retained message with the same topic, only retained messages replaces retained messages.
A scenario for using retained message:
A sensor measures the room temperature and update it every hour. If the temperatures are published as retained message, then the client will get a usable value whenever it connects, it doesn’t need to wait for a long time until a new value is published, and it will not be flooded by lots of unusable outdated value.
Notice: A retained message doesn’t belong to any session. It retains regardless the publishing session is clean or not. Also, it retains when a session is ended.