MQTT v5 introduced many new features and changed how some existing features work.
In this tutorial I will be covering all of these features with brief examples, and also in many case, links to detailed examples and videos.
Note: Examples used in the tutorial were created using the Mosquitto broker v1.6.2 and the Python client available on Github here.
I’ve divided the features into sections to make it easier to determine where they apply.
- Clean session/start
- Client Restrictions/Limitations
- Server Restrictions/Limitations
- Will Delay Interval
- User properties
- Server Redirect
Clean Sessions Or Clean Start
This has been renamed to clean start and works basically the same as before except that we now have a session expiry timer.
This tutorial covers clean sessions in MQTT3.11 and is still applicable to MQTTv5.
However in MQTTv5 if you set the clean session or start to false you need to provide a session expiry value. If you don’t then it is set to 0 which makes it basically the same as clean sessions True.
On the Python client that I used it is set in the client creation.
Example Python code:
client_sub = MQTTClient("subclient",clean_session=False,session_expiry_interval=300)
Sets the expiry time to 300 seconds.
This means that if a client disconnects and reconnects within an 5 minutes with clean start= False,QOS>1 then session state data ( e.g subscribed topics, queued messages) are retained.
However if the client disconnects and reconnects after 5 minutes with clean start= False,QOS>1 then session state data ( e.g subscribed topics, queued messages) are lost and the client must resubscribe to topics and messages sent while the client was disconnected are lost.
Why Use it? – It frees up server space as the server can clear all stored data for that client.
A client can now indicate to a server various client restrictions. It can tell the server to:
- Restrict size of messages to send to the client
- Restrict the number of QOS 1 and 2 messages
Message Size Restrictions
The client tells the server the maximum message size it it prepared to receive and any messages larger than this are dropped by the server.
Uses: Used by low powered clients that lack the memory to store the messages. See MQTT and Mosquitto Message size restrictions
The client tells the server to limit the number of QOS 1 and 2 messages that can be sent concurrently.
Uses: Again used by low powered clients as QOS 1 and 2 messages mean that the client needs send additional acknowledgement messages.
Providing certain functionality can strain server resources and so the server may not support them.
It is now possible for the server to indicate this is the message exchange using the properties field.
Example: The screen shot below shows the CONNACK message properties field From the Mosquitto Server.
There are many other limitations that the server can indicate.
By default if the server doesn’t indicate that it doesn’t support a particular feature then it is supported.
For example it is possible for the server not to support retain messages using the Retain Available property, but in the screen shot above it is not there, and so the server supports retain messages.
Will Delay Interval
This is used to specify a time delay in sending the will messages.
This prevents the will message being sent for a short connection interruption.
User properties are defined by the user and are a collection of key value pairs.
They can be used to send connection related properties from the Client to the Server.
They are not forwarded to the destination client. See user properties on publish below. and understanding MQTTv5 User Properties
Server Reference or Server Redirect
This is a very interesting feature as it allows the server to redirect the client to another broker/server. From the specification
The Server uses a Server Reference in either a CONNACK or DISCONNECT packet with Reason code of 0x9C (Use another server) or Reason Code 0x9D (Server moved) as described in section 4.13.
When a message is published with a QOS of 1 or 2 and the receiving client has:
- Connected with clean session of False
- Subcribed wuth a QOS or 1 or 2
Then the broker will hold published messages for the client if it is currently disconnected.
On MQTTv3 this was indefinite, but on v5 you can set the period that the server will hold the message before discarding.
This is done in the publish message below is a sample Python code snippet:
With the above setting then if the client doesn’t reconnect within 20 seconds the message is discarded.
Payload Format Indicator
Set on the Publish Message. There are only two possibilities.
- Binary – this is the same as v3.1
- utf-8 – new to v5
Uses: Useful at the receiver as is knows if it needs to decode the message payload.
These are defined by the user and are a collection of key value pairs.
Python = dictionary
keys=msg_number and time
values= 1 and 100
These are useful for sending information to the destination outside of the payload.
In v3.1.1 this information was usually sent as JSON encoded data as part of the payload.
So in v3.1.1 the payload would be:
This isn’t a problem if the payload is text data but if the payload is binary data then it will need to be converted using Base64 encoding.
User properties can be set in all packet types:
Publish user properties are sent to the destination.
Topic aliases were introduced in MQTT-SN and are mechanism for reducing the size of published packets by reducing the size of the topic.
A topic alias once established can be used in place of a topic string.
So it the topic houses/house1/upstairs/light1 had an alias or 1 then this could be used in place of the topic string when publishing messages.
Before you can use topic aliases the client must indicate the topic alias maximum number to the server.
By default if this isn’t set then it is 0 which means topic aliases aren’t allowed by the client.
See MQTTv5 Topic aliases for more details
Response Topic and Request /Response Pattern
In Web Applications the client(browser) makes a request and the server responds.
MQTT uses a publish and subscribe pattern where there is no direct communication between the sending client and the destination client/server.
Using the response topic in the publish message allows you to implement the request/response pattern that is common in Web applications.
Non Local Publishing
In MQTTv3.1.1 if you subscribe to the same topic as you publish on then you will receive all of the messages that you publish.
By Using the non local option the broker will not send you any messages that you have published.
This is a subscription option.
Retained Message Control
Retained messages still work as in 3.1.1 but subscribe options have been added to control what the client receives.:
0 -Send retained messages when client subscribes. Same as in MQTT 3.1.1
1 -Send retained messages when client subscribes. if the subscription does not currently exist.
2 – Don’t send retained messages when client subscribes.
Uses: Likely to help in implementing MQTT bridges.
This is optional and if used it is an integer associated with the subscription and used to filter incoming messages to correct message handler.
However this could also be done by analysing the topic itself as in MQTTv3.1.1
client.subscribe('test', qos=0, subscription_identifier=1) client.subscribe('test/#', qos=0, subscription_identifier=2)
The idea is to provided for client load balancing.
It is accomplished use the reserved topic $SHARE
The format is:
The sharename cannot be a wildcard character and must be at least 1 character.
See MQTTv5 Shared Subscriptions for more details
Reason Codes on All ACK Messages
In MQTTv3.1.1 there were very few indications from the server as to what went wrong during the various stages of :
- Establishing a connection
- Publishing a Message
- Subscribing to topics
All Acknowledgement packets (except PINGRESP) carry a reason code and there are 128 codes available.
Uses and example : Makes it much easier for an application to understand what has gone wrong and take the appropriate action.
A publish ACK with reason code 16 means that there are no matching subscribers. Therefore in MQTTv5 it is possible to detect if a topic is in use to some degree.
In MQQTv3.1.1 only the client could send the disconnect message.
If the server encountered problems it would simply terminate the TCP/IP session.
In MQTTv5 the server can send the client a disconnect message along with a reason code.
The screen shot below is taken from the MQTTv5 specification.
- MQTTv5 Specification
- A Story of MQTT 5.0
- Python MQTT v5.0 Client
- This Wiki details the differences between MQTT v3.1.1 and MQTT v5.0 .
- MQTT Client and Mosquitto Broker Message Restrictions With Examples
- MQTTv5 CONNECT and CONNACK Messages -Overview
- Understanding And Using MQTT v5 Request Response