MQTT 协议学习:Retained(保留消息) 与 LWT(最后遗嘱)
背景导入
让我们来看一下这个场景:
你有一个温度传感器,它每三个小时向一个 Topic 发布当前的温度。那么问题来了,有一个新的订阅者在它刚刚发布了当前温度之后订阅了这个主题,那么这个订阅端什么时候能才能收到温度消息?
对的,它必须等到三个小时以后,温度传感器再次发布消息的时候才能收到。在这之前,这个新的订阅者对传感器的温度数据一无所知。
怎么来解决这个问题呢?
这个时候就轮到 Retained 消息出场解决这个问题了。Retained 消息是指在 PUBLISH 数据包中 Retain 标识设为 1 的消息,Broker 收到这样的 PUBLISH 包以后,将保存这个消息,当有一个新的订阅者订阅相应主题的时候,Broker 会马上将这个消息发送给订阅者。
Retained 消息
Retain 消息有以下一些特点:
- 一个 Topic 只能有 1 条 Retained 消息,发布新的 Retained 消息将覆盖老的 Retained 消息;
- 如果订阅者使用通配符订阅主题,它会收到所有匹配的主题上的 Retained 消息;
- 只有新的订阅者才会收到 Retained 消息,如果订阅者重复订阅一个主题,也会被当做新的订阅者,然后收到 Retained 消息;
- Retained 消息发送到订阅者时,消息的 Retain 标识仍然是 1,订阅者可以判断这个消息是否是 Retained 消息,以做相应的处理。
注意:Retained 消息和持久性会话没有任何关系,Retained 消息是 Broker 为每一个 Topic 单独存储的,而持久性会话是 Broker 为每一个 Client 单独存储的。
如果你想删除一个 Retained 消息也很简单,只要向这个主题发布一个 Payload 长度为 0 的 Retained 消息就可以了。
那么开头我们提到的那个场景的解决方案就很简单了,温度传感器每 3 个小时发布当前的温度的 Retained 消息,那么无论新的订阅者什么时候进行订阅,它都能收到温度传感器上一次发布的数据。
LWT(最后遗嘱)
LWT 全称为 Last Will and Testament,也就是我们在连接到 Broker 时提到的遗嘱,包括遗嘱主题、遗嘱 QoS、遗嘱消息等。
顾名思义,当 Broker 检测到 Client 非正常地断开连接的时候,就会向遗嘱主题里面发布一条消息。遗嘱相关的设置是在建立连接的时候,在 CONNECT 数据包里面的 Variable header(可变头与) Payload(有效载荷) 中 指定的。
- Will Flag:是1否0使用 LWT
- Will Topic:遗嘱主题名,不可使用通配符(在 CONNECT报文中的 有效载荷 中 设置)
- Will Qos:发布遗嘱消息时使用的 QoS 等级,如果遗嘱标志(Will Flag)被设置为0,遗嘱QoS也必须设置为0(0x00)
- Will Retain:遗嘱消息的 Retain 标识
- Will Message:遗嘱消息内容(在 CONNECT报文中的 有效载荷 中 设置)
Broker 在以下情况下认为 Client 是非正常断开连接的:
- Broker 检测到底层的 I/O 异常;
- Client 未能在 Keep Alive 的间隔内和 Broker 之间有消息交互;
- Client 在关闭底层 TCP 连接前没有发送 DISCONNECT 数据包;
- Broker 因为协议错误关闭和 Client 的连接,比如 Client 发送了一个格式错误的 MQTT 数据包。
如果 Client 通过发布 DISCONNECT 数据包断开连接,这个属于正常断开连接,不会触发 LWT 的机制,同时,Broker 还会丢弃掉这个 Client 在连接时指定的 LWT 参数。
根据遗嘱的属性和触发机制,我们不难看出,遗嘱常用于获取设备的连接状态。
注意,设置好遗嘱以后还不够(因为你只要订阅者一启动就会收到遗嘱消息,如果此时发布者已经在线,会导致不准确),
所以,还需要在设备成功连接MQTT的时候主动发个消息,发送的主题必须和遗嘱的主题相同,设置好消息的 retain 属性,让其自动纠正过来。
MQTT 协议学习:Retained(保留消息) 与 LWT(最后遗嘱)的更多相关文章
- MQTT 协议学习: 总结 与 各种定义的速查表
背景 经过几天的学习与实操,对于MQTT(主要针对 v3.1.1版本)的学习告一段落,为了方便日后的查阅 本文链接:<MQTT 协议学习: 总结 与 各种定义的速查表> 章节整理 MQTT ...
- MQTT 协议学习:004-MQTT建立通信与 CONNECT 、CONNACK 报文
背景 上一讲 MQTT 协议学习:通信报文的构成介绍了在MQTT通信中,各报文的通信流程:从本讲开始,我们开始介绍实际中使用的报文,以及它们的组成. CONNECT - 连接请求 报文 客户端到服务端 ...
- MQTT 协议学习:005-发布消息 与 对应报文 (PUBLISH、PUBACK、PUBREC、PUBREL)
背景 当有订阅者订阅了有关的主题以后,通过发布消息的消息的动作,可以让订阅者收到对应主题的消息. 根据不同的QoS 等级,通信的动作也略有不同. PUBLISH – 发布消息 报文 PUBLISH控制 ...
- MQTT 协议学习:002- 通信报文的构成
背景 之前工作中参与有关协议调试的时候,发现对于协议帧的解析是比较重要的. 参考:<MQTT协议 -- 消息报文格式>.<基于STM32实现MQTT>.<MQTT协议从服 ...
- MQTT协议学习笔记
1.前沿 万物联网的时代即将到来,物联网也由当初的概念开始进一步落实.随着无线网络技术飞速发展,各种设备都可以连接网络,实现远程控制.例如智能家居最近非常火爆,智能插座.智能LED灯.智能摄像头等.在 ...
- MQTT 协议学习: QoS等级 与 会话
背景 QoS 等级 与 通信的流程有关,直接影响了整个通信.而且篇幅比较长,所以我觉得应该单独拎出来讲一下. 概念 QoS 代表了 服务质量等级. 设置上,由2 位 的二进制控制,且值不允许为 3(0 ...
- MQTT 协议学习:006-订阅主题 与 对应报文(SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK)
背景 之前我们提到了怎么发布消息对应的报文:现在我们来看,订阅一个主题的报文是怎么样的. SUBSCRIBE - 订阅主题 客户端向服务端发送SUBSCRIBE报文用于创建一个或多个订阅.每个订阅注册 ...
- MQTT协议学习总结
一.MQTT介绍 MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通 ...
- MQTT协议学习研究 & Mosquitto简要教程(安装和使用)
若初次接触MQTT协议,可先理解以下概念: [MQTT协议特点]——相比于RESTful架构的物联网系统,MQTT协议借助消息推送功能,可以更好地实现远程控制. [MQTT协议角色]——在RESTfu ...
- MQTT协议学习及实践(Linux服务端,Android客户端的例子)
前言 MQTT(Message Queuing Telemetry Transport),是一个物联网传输协议,它被设计用于轻量级的发布/订阅式消息传输,旨在为低带宽和不稳定的网络环境中的物联网设备提 ...
随机推荐
- 3_05_MSSQL课程_Ado.Net_SQLDataAdapter
using System; using System.Collections.Generic; using System.ComponentModel; using System.Configurat ...
- NLP的比赛和数据集
整理了NLP领域的比赛.数据集.模型 比赛 网站 主办方(作者) decaNLP http://decanlp.com/ Salesforce CLUE https://github.com/CLUE ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)D(树状数组)
//树状数组中数组的特性,有更巧妙的方法.//我们知道在树状数组中,对于数组tree[i],它所维护的区间为[i−lowbit(i)+1,i]//所以对于tree[2^i],它所维护的区间就为[1,2 ...
- LCS(最长公共子序列)
这个问题很有意思,在生物应用中,经常需要比较两个(或多个)不同生物体的DNA片段.例如,某种生物的DNA可能为S1 = ACCGGTCGAGTGCGCGGAAGCCGGCCGAA,S2 = GTCGT ...
- Manacher 算法学习笔记
算法用处: 解决最长回文子串的问题(朴素型). 算法复杂度 我们不妨先看看其他暴力解法的复杂度: \(O(n^3)\) 枚举子串的左右边界,然后再暴力判断是否回文,对答案取 \(max\) . \(O ...
- Java日志介绍(2)-Log4j
Log4j是Apache的一个开源项目,官网地址为http://logging.apache.org/log4j/1.2/index.html.通过使用Log4j,可控制日志信息输出到控制台.文件.数 ...
- 136、Java的内部类
01.代码如下: package TIANPAN; class Outer { // 外部类 private String msg = "Hello World !"; class ...
- Flask - 请求扩展,钩子函数(Django的中间件) --> 请求前,中,后,
例子1. 处理请求之前 @app.before_request 在请求之前,这个被装饰的函数会被执行 用户登录验证代码可以在这里写 @app.before_request def process_re ...
- 虚拟对抗训练(VAT):一种用于监督学习和半监督学习的正则化方法
正则化 虚拟对抗训练是一种正则化方法,正则化在深度学习中是防止过拟合的一种方法.通常训练样本是有限的,而对于深度学习来说,搭设的深度网络是可以最大限度地拟合训练样本的分布的,从而导致模型与训练样本分布 ...
- 学习redis
https://blog.csdn.net/xiaoyiyz/article/details/60613165 https://bbs.csdn.net/topics/392277304 https: ...