MQTT 关键特性详解
MQTT 关键特性详解:保留消息 (Retain) 与遗嘱消息 (LWT)
前言:解决两个核心问题
在物联网(IoT)的世界里,我们经常遇到两个问题:
“现在是什么状态?” 当一个设备或 App 刚上线时,它如何能立刻知道它所关心的设备(比如一个灯、一个传感器)的当前状态,而不需要傻等下一次状态更新?
“它还活着吗?” 如果一个重要的设备因为断电或网络故障意外掉线了,我们如何能及时发现并通知其他系统?
MQTT 的“保留消息”和“遗嘱消息”正是为了优雅地解决这两个问题而设计的。
1. Retained Message (保留消息) - “会议室门口的状态牌”
想象一下,一个会议室门口挂着一个牌子,上面写着“使用中”或“空闲”。
普通消息:就像有人在会议室门口喊了一声:“现在里面有人了!”。如果你正好路过,就听到了。但如果你是后来的,你就错过了这条信息,只能看着紧闭的门干着急,不知道里面到底有没有人。
保留消息:就像每次会议室状态变化时,有人都会去更新门口那个状态牌。这个牌子会一直挂在那里。任何时候,任何人(新的订阅者)来到这个会议室门口,只要看一眼牌子,就能立刻知道当前的状态,无需等待下一次状态更新。
在 MQTT 中,这个“状态牌”就是 保留消息。
场景带入:会议室预定系统
主题 (Topic):
company/meeting_room/A101/status
发布者:一个控制面板,当有人预定或离开时,它会发布消息。
工作流程
发布状态(带 Retain 标志): 张三进入会议室,在控制面板上点击“开始会议”。面板立刻向主题
company/meeting_room/A101/status
发布一条消息,内容为{"status": "In Use", "user": "张三"}
,并且设置Retain
标志位为true
。Broker 的行为:Broker 收到这条消息后,除了把它发给当前所有订阅了该主题的客户端外,还会像拍照一样,把这条消息“钉”在
company/meeting_room/A101/status
这个主题上,作为这个主题的“最新快照”。
新订阅者获取状态: 半小时后,李四打开公司的预定 App(一个新的客户端),想要查看 A101 会议室的状态。他的 App 一订阅
company/meeting_room/A101/status
这个主题。Broker 的行为:Broker 发现有新订阅者,立刻检查这个主题上有没有“钉”着的消息快照。它发现有,于是立即将
{"status": "In Use", "user": "张三"}
这条保留消息发送给李四的 App。
结果: 李四的 App 瞬间就显示出“使用中”,而不需要等待张三开完会或者下一个人来更新状态。
用途总结:保留消息非常适合用来发布那些“状态性”的信息,确保任何新的订阅者都能立即获得最新的状态。
2. Last Will and Testament (LWT, 遗嘱消息) - “紧急联系人便条”
你可以把“遗嘱消息”想象成你出远门前,在桌上给家人留的一张便条。你告诉家人(Broker):“我每天都会报平安(正常心跳)。如果有一天我突然失联了(异常断开),没来得及跟你们说再见,那就把我桌上这张写着‘我出事了,速来!’的便条公之于众。”
正常断开 (Disconnect):你旅行结束,正常回家了。你亲口告诉家人你回来了,那张便条自然也就没用了,被悄悄收了起来。
异常断开 (Unexpected Disconnect):你中途失联了。家人发现联系不上你,就会把那张“遗嘱便条”拿出来,告诉所有关心你的人。
场景带入:会议室控制面板的在线状态
遗嘱主题:
company/meeting_room/A101/connection_status
客户端:会议室的控制面板。
工作流程
连接并设置“遗嘱”: 控制面板启动时,它向 Broker 发起连接请求。在这个请求里,它“藏”了一个遗嘱:
遗嘱主题 (Will Topic):
company/meeting_room/A101/connection_status
遗嘱消息 (Will Message):
OFFLINE
遗嘱 QoS: 1 (确保遗嘱一定能被发布)
遗嘱 Retain: true (让这个 OFFLINE 状态也成为一个“状态牌”)
正常工作: 连接成功后,控制面板可以周期性地向
.../connection_status
主题发布ONLINE
消息,表示自己工作正常。发生意外: 突然,清洁工不小心踢掉了电源插头,控制面板瞬间断电。它根本没机会告诉 Broker 它要“正常下线”了。
Broker 执行遗嘱: Broker 通过心跳机制发现控制面板失联了。它判定这是一次“异常断开”,于是立即执行之前设定好的遗嘱:将消息
OFFLINE
发布到company/meeting_room/A101/connection_status
这个主题上。结果: 公司的IT运维系统(它一直订阅着所有设备的状态主题)立刻收到了这条
OFFLINE
消息,马上触发警报,通知管理员“A101会议室的控制面板掉线了,请立即检查!”。
用途总结:遗嘱消息是监控设备是否“健在”的完美机制,用于在设备异常离线时,由 Broker 主动发出通知。
总结对比
特性 | Retained Message (保留消息) | Last Will and Testament (遗嘱消息) |
---|---|---|
谁发布? | 客户端主动发布。 | Broker 在客户端异常断开时代为发布。 |
何时发布? | 在任何需要更新状态的时候。 | 仅在客户端异常断开连接时。 |
解决什么问题? | 让新订阅者能立即获取最新状态。 | 让其他系统能及时发现设备异常掉线。 |
好搭档 | 遗嘱消息本身也可以被设置为保留消息,这样设备掉线的状态也能被后来的订阅者立即获取。 |