Will messages are MQTT's ability to gracefully send wills to third parties for those devices that may experience unexpected Unexpected disconnects include but are not limited to:
- Due to network failure or network fluctuations, the device fails to communicate within the keep-connection period, and the connection is closed by the server
- The device loses power unexpectedly
- The connection is closed by the server when the device attempts to perform an unallowable operation, such as subscribing to topics other than its own permissions, etc.
The will message can be regarded as a simplified version of the PUBLISH message, which also contains fields such as Topic, Payload, and QoS. The will message will be specified by the CONNECT message when the device is connected to the server, and then the server will publish the will message to the will topic (Will Topic) specified at the time of connection when the device is disconnected unexpectedly. This also means that the server must complete the storage of the will message before replying to CONNACK, so as to ensure that the server can guarantee that the will message is published in the event of an unexpected disconnection at any time afterward.
The following are the differences between will messages in MQTT 5.0 and MQTT 3.1 & 3.1.1:
MQTT 5.0 | MQTT 3.1 & 3.1.1 | |
---|---|---|
Will Retain | Yes | Yes |
Will QoS | Yes | Yes |
Will Flag | Yes | Yes |
Will Properties | Yes | No |
Will Topic | Yes | Yes |
Will Payload | Yes | Yes |
The uses of Will Retain, Will QoS, Will Topic, and Will Payload are basically the same as those of ordinary PUBLISH packets, and will not be repeated here.
The only thing worth mentioning is the use case of Will Retain, which is a combination of retention messages and will messages. If the client subscribed to the will topic (Will Topic) cannot guarantee that the will message is online when the will message is published, it is recommended to set Will Retain for the will message to prevent the subscriber from missing the will message.
Will Flag is usually a field concerned by MQTT protocol implementers. It is used to identify whether the CONNECT message will contain fields such as Will Properties and Will Topic.
The last one is the Will Properties field newly added in MQTT 5.0. The property itself is also a new feature of MQTT 5.0. Different types of messages have different properties. For example, CONNECT messages have Session Expiry Interval and maximum message length. (Maximum Packet Size) and other attributes, and SUBSCRIBE packets have attributes such as Subscription Identifier.
Attributes such as Message Expiry Interval in Will Properties are basically the same as those in the PUBLISH message. Only one Will Delay Interval is a unique attribute of Will messages.
The will delay interval, as the name suggests, is to delay the release of the will message after the connection is disconnected for a period of time. One of its important uses is to avoid sending a will message when the device is temporarily disconnected due to network fluctuations, but can quickly restore the connection to continue providing services, and cause confusion to the will message subscribers.
It should be noted that the specific delay in publishing the will message, in addition to the will delay interval, is also limited by the session expiration interval, which depends on which of the two occurs first. So when we set the session expiration interval to 0, i.e. the session expires when the network connection is closed, then regardless of the value of the will delay interval, the will message will be published as soon as the network connection is lost.
Demonstrate the use of will messages
Next, we use EMQ X and MQTT X to demonstrate the actual use of will messages.
In order to achieve the effect that the MQTT connection is abnormally disconnected, we need to adjust the default ACL rules and related configuration items of EMQ X:
First etc/acl.conf
, which means that the local client connection is refused to publish the test topic. Note that this needs to be added before all default ACL rules to ensure this rule takes effect successfully:
{deny, {ipaddr, "127.0.0.1"}, publish, ["test"]}.
Then modify the etc/emqx.conf
configuration item in zone.internal.acl_deny_action
and set it to disconnect the client when the ACL check is rejected:
zone.internal.acl_deny_action = disconnect
After completing the above modifications, we start EMQ X.
Next, we create a new connection named demo in MQTT X, change the Host to localhost, select MQTT Version as 5.0 in the Advanced section, and set the Session Expiry Interval to 10 to ensure that the session will not expire before the will message is published.
Then in the Lass Will and Testament section set the Last-Will Topic to offline, the Last-Will Payload to I'm offline
and the Will Delay Interval (s) to 5.
After completing the above settings, we click the Connect button in the upper right corner to establish the connection.
Then we create a client connection named subscriber and subscribe to the offline topic.
Next, we go back to the demo connection and publish an arbitrary content message with the topic test. At this time, the connection will be disconnected, wait patiently for five seconds, and we will see that the subscriber connection has received a will message with the I‘m offline
Advanced usage scenarios
Here's how to use the Retained message in conjunction with the Will message.
- Client A will set the message content
offline
, which will transmit a common topic and theme is set to a state withA/status
. - When the client A is connected to the theme
A/status
send content toonline
Retained message, other clients subscribe to the topicA/status
time, you will get to Retained messageonline
. - When client A disconnects abnormally, the system automatically sends
offline
A/status
, and other clients subscribed to this topic will immediately receive theoffline
message; if the will message is set to Will Retain, then if there is a new message at this time The client that subscribes to theA/status
online, and will also get the will message with theoffline
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。