Use of the MQTT subscription option

In the introduction to the MQTT publish/subscribe mode blog, we have learned that we need to initiate a subscription to the server before receiving corresponding messages from the server. If the topic filter specified when subscribing determines which topics the server will forward to us, then the subscription option allows us to further customize the forwarding behavior of the server.

In this article, we will focus on what subscription options are available to us in MQTT and how to use them.

subscription options

In MQTT, a subscription consists of a topic filter and corresponding subscription options. So in theory, we could have different subscription options for each subscription.

MQTT 5.0 provides four subscription options, namely QoS, No Local, Retain As Published, and Retain Handling, while MQTT 3.1.1 only provides one subscription option of QoS. However, the default behavior of these new subscription options in MQTT 5.0 is still consistent with MQTT 3.1.1, which will be very friendly if you are planning to upgrade from MQTT 3.1.1 to MQTT 5.0.

Now, let's take a look at what these subscription options do.

QoS

QoS is the most commonly used subscription option, which indicates the maximum QoS level that the server can use when sending messages to the subscriber.

A client may specify a QoS less than 2 when subscribing because its implementation does not support QoS 1 or QoS 2. However, if the maximum QoS supported by the server is less than the maximum QoS requested by the client when subscribing, then obviously the server will not be able to meet the client's requirements, and the server will notify the subscriber of the final grant through the subscription response message (SUBACK). The maximum QoS level, the subscriber can evaluate whether to accept and continue the communication by itself.

image.png

A simple calculation formula:

服务端最终授予的最大 QoS = min ( 服务端支持的最大 QoS, 客户端请求的最大 QoS )

However, the maximum QoS we request when subscribing does not limit the QoS used by the publisher when publishing messages. When the maximum QoS requested when we subscribe is less than the QoS when the message is published, in order to deliver the message as much as possible, the server will not ignore these messages, but will downgrade the QoS of these messages when forwarding.

image.png

Similarly, we also have a simple calculation formula:

消息被转发时的 QoS = min ( 消息原始的 QoS, 服务端最终授予的最大 QoS )

No Local

No Local has only two possible values, 0 and 1. If it is 1, it means that the server cannot forward the message to the client that published the message, and if it is 0, it is the opposite.

This option is usually used in bridging scenarios. The essence of bridging is that two MQTT servers establish an MQTT connection, and then subscribe to some topics with each other. The server forwards the client's message to another server, and the other server can continue to forward the message to its client.

image.png

In the simplest example, we assume that two MQTT Servers are Server A and Server B, and they subscribe to each other's #topics respectively. Now, Server A forwards some messages from the client to Server B, and when Server B looks for a matching subscription, Server A is there too. If Server B forwards the messages to Server A, then Server A will forward them to Server B again after receiving the messages, thus falling into an endless forwarding storm.

And if Server A and Server B #set the No Local option to 1 while subscribing to the topic, this problem can be perfectly avoided.

Retain As Published

Retain As Published also only has two possible values, 0 and 1. If it is 1, it means that the server needs to keep the Retain flag in the message unchanged when forwarding the application message to this subscription, and if it is 0, it means it must be cleared.

Retain As Published, like No Local, is also mainly suitable for bridging scenarios. We know that when the server receives a retained message, in addition to storing it, it will also forward it to existing subscribers like a normal message, and the Retain flag of the message will be cleared when forwarding.

This poses some problems in bridging scenarios. We continue to use the previous setting. When Server A forwards the retained message to Server B, since the Retain flag in the message has been cleared, Server B will not know that this is originally a retained message, and naturally will not store it. As a result, retained messages cannot be used across bridges.

Then in MQTT 5.0, we can let the bridge server set the Retain As Published option to 1 when subscribing to solve this problem.

image.png

Retain Handling

Retain Handling This subscription option is used to indicate to the server whether to send a retain message when the subscription is established.

We know that by default, as long as the subscription is established, the reserved messages matching the subscription in the server will be delivered.

But sometimes, the client may not want to receive the reserved message. For example, the client reused the session when connecting, but the client cannot confirm whether the subscription was successfully created in the last connection, so it may initiate the subscription again. If the subscription already exists, the reserved message may have been consumed, or the server may have cached some messages that arrived during the offline period in the session. At this time, the client may not want the server to publish the reserved message.

Alternatively, the client may not want to receive the retain message at any point, even for the first time subscribed. For example, we send the switch state as a reserved message, but for a certain subscriber, the switch event will trigger some operations, so it is useful not to send the retained message in this case.

These three different behaviors can be selected through Retain Handling.

  • Set Retain Handling to 0, which means that as long as the subscription is established, the retention message will be sent;

  • Set Retain Handling to 1, which means that the retention message will only be sent when a new subscription is established instead of a repeated subscription;

  • Set Retain Handling to 2, which means do not send retain messages when the subscription is established.

demo

Demo of Subscription Option QoS

  1. Access MQTTX Web on a web browser .

  2. Create an MQTT connection using WebSocket and connect to a free public MQTT server:

    MQTTX

  3. After the connection is successful, we subscribe to the topic mqttx_4299c767/demoand specify QoS as 0. Since the public server may be used by many people at the same time, in order to avoid repeating the topic with others, we can use the Client ID as the topic prefix:

    Subscribe to the topic "mqttx_4299c767/demo"

  4. mqttx_4299c767/demoAfter the subscription is successful, we publish a QoS 1 message to the topic . At this time, we will see that we have sent a QoS 1 message, but received a QoS 0 message, which indicates that QoS degradation has occurred:

    Publish a QoS 1 message

Demo of subscription option No Local

  1. Access MQTTX Web on a web browser.

  2. Create an MQTT connection using WebSocket and connect to a free public MQTT server.

  3. After the connection is successful, we subscribe to the topic mqttx_4299c767/demoand set No Local to true:

    Subscribe to the topic "mqttx_4299c767/demo"

  4. After the subscription is successful, as in the previous QoS demonstration, we still publish the message by the subscriber itself, but this time we will find that the subscriber will not be able to receive the message:

    Publish MQTT Message

Demo of subscription option Retain As Published

  1. Access MQTTX Web on a web browser.

  2. Create an MQTT connection using WebSocket and connect to a free public MQTT server.

  3. After the connection is successful, we first subscribe to the topic mqttx_4299c767/rap0and set Retain As Published to false, then subscribe to the topic mqttx_4299c767/rap1and set Retain As Published to true:

    Subscribe to the topic "mqttx_4299c767/rap0"

    Subscribe to the topic "mqttx_4299c767/rap1"

  4. After the subscription is successful, we publish a retained message to the topic mqttx_4299c767/rap0and respectively, we will see that the Retain flag in the message received by the former is cleared, while the Retain flag in the message received by the latter is retained:mqttx_4299c767/rap1

    Receive messages

Demo of subscription option Retain Handling

  1. Access MQTTX Web on a web browser.

  2. Create an MQTT connection using WebSocket and connect to a free public MQTT server.

  3. After a successful connection, we first mqttx_4299c767/rhpublish a reserved message to the topic . Then subscribe to the topic mqttx_4299c767/rhand set Retain Handling to 0:

    Publish a retained message to the topic "mqttx_4299c767/rh"

  4. After the subscription is successful, we will receive the reserved message sent by the server:

    Receive the retained message

  5. Cancel the current subscription, re-subscribe the topic mqttx_4299c767/rh, and set Retain Handling to 2. However, after the subscription is successful this time, we will not receive the reserved message sent by the server:

    Retain Handling set to 2

In MQTTX, we have no way to demonstrate the effect of setting Retain Handling to 1. You can however get a Python sample code for subscription options here .

Copyright statement: This article is original by EMQ, please indicate the source for reprinting.
Original link: https://www.emqx.com/zh/blog/an-introduction-to-subscription-options-in-mqtt

Guess you like

Origin blog.csdn.net/emqx_broker/article/details/131813030
Recommended