遗言 - MQTT 核心系列:第九章
欢迎来到MQTT核心系列的第九章。这个系列一共有十章,用来介绍MQTT的核心特性和概念。在这一章,我们将讲解MQTT中的遗言特性。
因为MQTT会运行在网络不好的环境中。可以合理的假设,在这些环境中,客户端偶尔会不正常的断开连接。原因包括连接丢失,电量为空等等。了解客户端是正常断连(发送了DISCONNECT消息)还是非正常断连(没有发送DISCONNECT消息),这对你正确做出响应有帮助。遗言特性为客户端对非正常断连做出响应提供了合适的途径。
遗言
在MQTT中,你可以使用遗言去通知其它设备有一个设备异常断连了。每一个客户端在它连接代理的时候都能定义它的遗言。遗言是一个包含主题,保留信息标志,QoS,和负载的普通消息。代理会一直存储该消息,直到该客户端异常断连。面对异常断连,代理会发送遗言给所有订阅了该遗言的主题的客户端。但是如果一个客户端是通过发送DISCONNECT消息正常断连的,代理会丢弃存储的遗言。
当一个客户端异常断连时,遗言能帮助你实现各种策略(至少可以通知其它客户端该客户端的离线状态)。
怎么为一个客户端指定遗言
客户端可以在发送CONNECT消息的时候指定遗言。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OGdbnf0F-1613554185350)(https://www.hivemq.com/img/blog/connect.png)]
代理什么时候发送遗言?
根据MQTT3.1.1的标准,代理在以下情形下必须发送遗言:
- 代理检测到I/O错误或者网络错误
- 客户端在指定的存活时间内没有联系代理
- 客户端在关闭网络连接前没有发送DISCONNECT数据包
- 由于协议错误,代理关闭了网络连接
我们将在下一章学习存活时间
最佳实践-什么时候你需要使用遗言
遗言是一种通知其它客户端一个客户端意外断连的好方法。在真实场景中,遗言通常会与保留消息一起使用来存储客户端的状态。例如,客户端1先发送了一个CONNECT消息给代理,这个消息中包含一个负载为"Offline"的遗言,遗言的主题为"client1/status",并且这个遗言的lastWillRetain标志被设置为true。
接着,客户端发送一个PUBLISH消息到"client1/status",这个消息的负载为"Online"且保留保留信息标志为true。那么只要客户端1保持连接状态,那么新订阅"client1/status"的客户端就会收到"Online"的保留消息。如果客户端1异常断连,代理就会发送之前设置的遗言,并把主题"client1/status"的保留消息更新为"Offline"状态。那么再有客户端订阅了"client1/status"就会收到状态为"Offline"的保留消息。这种保留消息的模式能在其他客户端更新特定主题的状态。
以上就是第九章的所有内容了。在下一章,我们将讲解MQTT的心跳机制和代理是如何知道客户端是在线还是离线的。