📡 MQTT 保留消息特性解析与场景应用
🎯 1. 选题背景与核心价值
一句话问题定义: 设备刚上线,如何“立刻”知道系统当前状态?
🤔 为什么选择这个选题?
在物联网(IoT)系统中,状态不同步是一个高频痛点:
- 📱 手机 APP 打开智能灯,却不知道灯现在是 开 / 关
- 🌡️ 监控系统上线,却要等下一次传感器上报
- ⏳ 用户体验:等 = 难受
如果只用普通 MQTT 消息:
订阅者不在线 → 消息直接蒸发 💨
💎 核心价值总结
🟩 MQTT 保留消息(Retained Messages) 的本质是:
把“最新状态”钉在服务器上
| 价值点 | 说明 |
|---|---|
| ⚡ 即时性 | 新订阅者上线立刻拿到最新数据 |
| 🔗 解耦 | 发布者不关心谁订阅,系统更优雅 |
| 🧠 状态思维 | 非“事件”,而是“当前状态” |
👥 2. 小组成员及分工
-
👨💻 [姜政宇 张金榜]
选题定稿|EMQX 服务器搭建|MQTTX 测试|Markdown制作 -
📚 [陈航宇 李圣源]
资料搜集|MQTT 保留消息覆盖与清除机制测试 -
📝 [王怡婷 李亚轩 马豪苒]
文档整理|答辩汇报|技术总结
🧠 3. 核心知识点概述
❓ 什么是 MQTT 保留消息?
🔹 普通 MQTT 消息:
“我发了,你不在,那就算了。”
🔹 保留消息(Retained Message):
“这是我目前最新的状态,谁来都能看到。”
📌 技术本质:
- 发布消息时,将 Retain 标志设为
true - Broker 会保存该 Topic 下的 最后一条消息
⚙️ 关键特性速览
🟦 1️⃣ 唯一性(覆盖机制)
- 每个 Topic 只保留 1 条消息
- 新的 Retain 消息会直接覆盖旧的
🟨 2️⃣ 持久性(服务器级)
- 只要 Broker 不重启 / 未清除
- 状态就一直存在
🟥 3️⃣ 清除方式(很多人会忘)
Topic 不变
Payload = 空(0 字节)
Retain = true
✅ 这不是 bug,这是 官方设计
🌱 4. 场景应用演示
🏡 场景:智能大棚环境监控系统
🧠 业务背景:
- 🌡️ 温度传感器:每 10 分钟 上报一次环境温度
- 📱 管理员打开监控 APP,希望做到:
“不用等待下一次上报,打开就能看到当前温度。”
🎯 设计目标:
利用 MQTT 保留消息(Retained Message) 机制,在服务器侧保存“最新一次状态”,实现客户端的即时状态同步。
🧪 实验操作流程(基于 MQTTX 实测)
为验证 MQTT 保留消息的实际效果,我们使用 MQTTX 客户端 连接
EMQX 公共服务器 broker.emqx.io 进行模拟实验。
🟢 Step 1:传感器上报数据(发布保留消息)
首先,模拟温度传感器向指定主题发布一条温度数据,并勾选 Retain 标志。

图 1:MQTTX 发布端配置界面,右下角 Retain 选项已开启
关键配置参数:
- Topic:
greenhouse/sensor/temp - Payload:
26.5℃ - Retain:
True✅(核心设置)
📌 说明:
该消息发布后,即使发布端(传感器)断电或离线,Broker 仍会保存该 Topic 下的最新温度值。
🔵 Step 2:管理员查看数据(验证“秒收”效果)
随后,模拟管理员手机 APP 上线,新建 MQTT 连接并订阅同一主题:
greenhouse/sensor/temp

图 2:订阅端刚建立连接,即刻收到 26.5℃ 的历史保留消息
🎉 实验现象与结论:
- 订阅完成后,客户端在毫秒级时间内收到温度数据
- 无需等待下一次传感器上报
- 成功实现 “打开即显示当前状态” 的效果
该实验验证了 MQTT 保留消息在状态持久化与新订阅者同步方面的有效性。
📊 技术原理时序图(实验过程抽象)
sequenceDiagram
participant Sensor as 🌡️ 传感器 (Publisher)
participant Broker as ☁️ EMQX 服务器
participant App as 📱 手机 APP (Subscriber)
Note over Sensor, Broker: ① 传感器发布温度数据(Retain=True)
Sensor->>Broker: Publish "26.5℃" [Retain=True]
Broker->>Broker: 存储最新状态(26.5℃)
Note over Sensor: 传感器断电 / 进入休眠状态 😴
Note over App, Broker: ② 管理员稍后打开 APP
App->>Broker: Subscribe greenhouse/sensor/temp
Note over Broker, App: ③ Broker 立即下发保留消息
Broker-->>App: "26.5℃"(立刻收到)
💻 代码实现(Qt 核心逻辑示例)
// 1️⃣ 传感器端:发布保留消息
QMqttTopicName topic = "greenhouse/sensor/temp";
QByteArray payload = "26.5℃";
// publish(topic, payload, qos, retain)
// retain = true 表示开启保留消息
client->publish(topic, payload, 1, true);
🧩 5. 保留消息的工程实践与注意事项
🔍 5.1 保留消息 vs 普通消息 vs 离线消息
| 对比维度 | 普通消息 | 保留消息(Retain) | 离线消息 |
|---|---|---|---|
| 是否存储 | ❌ 不存储 | ✅ 仅存最新一条 | ✅ 存储多条 |
| 面向场景 | 事件通知 | 状态同步 | 可靠投递 |
| 新订阅者 | 收不到 | 立刻收到 | 取决于会话 |
| 常见用途 | 告警、日志 | 设备状态 | 指令下发 |
📌 结论:
保留消息关注的是“现在是什么状态”,而不是“过去发生了什么”。
⚠️ 5.2 使用保留消息时的常见误区
-
误把保留消息当数据库
保留消息只保存“最后一条”,并不适合历史数据存储。 -
频繁更新大 Payload
大数据量 + 高频 Retain 更新,会增加 Broker 压力。 -
忘记清除旧状态
设备退役或 Topic 不再使用时,应主动清除保留消息。
🔐 5.3 与 QoS 等级的关系说明
- QoS 0:最快,但可能丢消息(一般不推荐用于状态)
- QoS 1:至少一次,适合大多数状态同步场景 ✅
- QoS 2:最可靠,但开销最大(状态类很少使用)
📌 实际工程中,Retain + QoS 1 是最常见组合。
🧠 5.4 结合遗嘱消息(LWT)的典型设计
在真实系统中,保留消息常与 LWT(Last Will and Testament) 结合使用:
- 设备上线 → 发布
online(Retain=true) - 设备异常掉线 → Broker 自动发布
offline(Retain=true)
这样后台系统在任何时刻都能看到设备真实在线状态。
✅ 6. 小结
🟢 MQTT 保留消息 ≠ 离线消息
🟢 它解决的是:
- 状态同步问题
- 新设备 / 新客户端冷启动问题
🟢 非常适合:
- 智能家居 🏠
- 设备状态面板 📊
- 监控类系统 👀