This section describes the basic components of MQTT and how they work. We'll review publishing and subscribing to messages, using topics, subscribing with wildcards, using quality of service to guarantee message delivery, clearing sessions, and keeping connections alive.
MQTT implements the brokered publish/subscribe pattern, which decouples a client ("publisher," those sending a particular message) from other clients ("subscribers," those receiving the message). This means that the publisher and subscribers don't know about the existence of one another. The clients do not know each other, but they know the message broker, which filters all incoming messages and distributes them to the correct subscribers.
To demonstrate this process, the figure below shows a temperature sensor publishing temperature telemetry to the “temperature” topic on an MQTT Broker, which then delivers the telemetry to a laptop and a mobile device — subscribers to the “temperature” topic.
Figure 1: MQTT publish/subscribe
This decoupling of sender and receiver can be differentiated in three dimensions:
- Space decoupling – Publisher and subscriber do not need to know each other (e.g., by IP address and port).
- Time decoupling – Publisher and subscriber do not need to be connected at the same time.
- Synchronization decoupling – Operations on both components are not halted during publishing or receiving messages.
MQTT Message Types
MQTT has 14 different message types. Typically, end users only need to employ the CONNECT, PUBLISH, SUBSCRIBE, and UNSUBSCRIBE message types. The others are used for internal mechanisms and message flows.
Table 1: MQTT message types
Client request to connect to server
A message that represents a new/separate publish
QoS 1 response to a PUBLISH message
First part of QoS 2 message flow
Second part of QoS 2 message flow
Last part of the QoS 2 message flow
A message used by clients to subscribe to specific topics
Acknowledgement of a SUBSCRIBE message
A message used by clients to unsubscribe from specific topics
Acknowledgement of an UNSUBSCRIBE message
Heartbeat message acknowledgement
||Graceful disconnect message sent by clients before disconnecting
A topic is a UTF-8 string that is used by the broker to filter messages for each connected client. A topic consists of one or more topic levels, each of which is separated by a forward slash (topic level separator). In comparison to a message queue, a topic is lightweight. There is no need for a client to create the desired topic before publishing or subscribing to it because a broker accepts each valid topic without any prior initialization.
MQTT Topic Wildcards
MQTT Topic Wildcards can be used for topic filters when subscribing to MQTT messages. These wildcards are useful if a client wants to receive messages for different topics with similar structure at once. Wildcards are not allowed in topic names when publishing messages. The wildcard characters are reserved and must not be used in the topic. These characters cannot be escaped.
Table 2: MQTT Topic Wildcards
Matches one complete topic level, must occupy an entire topic level, and can be used more than once in a topic subscription
|Matches any number of levels within a topic; must be the last character of a topic subscription
Valid MQTT topic examples:
Each MQTT publish is sent with one of three Quality-of-Service (QoS) levels that are associated with different guarantees with regard to the reliability of message delivery. Both client and broker provide additional persistence and redelivery mechanisms to increase reliability in case of network failures, restarts of the application, and other unforeseen circumstances.
MQTT relies on TCP, which has reliability guarantees on its own. Historically, QoS levels were needed to overcome data loss on older and unreliable TCP networks. This can still be a valid concern for mobile networks today.
- Level 0: At most once delivery – The sender tries to send the message with best effort and relies on the reliability of TCP. No retransmission takes place.
- Level 1: At least once delivery – The receiver will get the message at least once. If the receiver does not acknowledge the message, or the acknowledgement gets lost on the way, it will be resent until the sender gets an acknowledgement. Duplicate messages can occur.
- Level 2: Exactly once delivery – The protocol makes sure that the message will arrive exactly once at the receiver. This increases communication overhead but is the best option when neither loss nor duplication of messages are acceptable.
Last Will and Testament
A Last Will and Testament (LWT) message can be specified by an MQTT client when connecting to the MQTT broker. If that client does not disconnect gracefully, the broker sends out the LWT message on behalf of the client when connection loss is detected.
Each sent MQTT message can be sent as a retained message. A retained message is a last known good value and persists at the MQTT broker for the specified topic. Every time a new client subscribes to that specific topic, it will instantly receive the last retained message on that topic. This is also the case for matching wildcards.
When a client connects to an MQTT broker, it has the choice of requesting a persistent session. The broker is responsible for storing session information of the client if the client requested a persistent session. The session information of a client includes:
- All subscriptions of the client
- All QoS 1 and 2 messages that are not processed yet
- All QoS 1 and 2 messages the client missed while being offline
Persistent sessions are often used for MQTT clients on constrained devices and clients that must not miss any messages for certain topics — not even when they are disconnected. When a client reconnects, the broker will send all missed messages for a subscription with a QoS level of 1 or 2. Persistent sessions are most useful for clients that subscribe to topics; publishing-only clients don't profit from persistent sessions.
Clean sessions are often used by publishing-only MQTT clients that are not interested in any state.
An MQTT CONNECT message contains a
keepAlive value in seconds, where the client can specify the maximum timeout between message exchanges. This allows the broker to detect a half-open connection and close the connection to the (already disconnected) client if the
keepAlive value is exceeded by more than 150% of the value.
So if a connection between broker and client is still established, the client sends a PINGREQ message to the broker within the
keepAlive interval if no other message exchange occurs. The broker responds with a PINGRESP message.
Every client specifies its
keepAlive value when connecting, and the maximum value is 65535 seconds (18h 12m 15s).