跳到主要内容

📡 MQTT 保留消息特性解析与场景应用

· 阅读需 5 分钟

🎯 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 选项已开启

关键配置参数

  • Topicgreenhouse/sensor/temp
  • Payload26.5℃
  • RetainTrue ✅(核心设置)

📌 说明
该消息发布后,即使发布端(传感器)断电或离线,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 使用保留消息时的常见误区

  1. 误把保留消息当数据库
    保留消息只保存“最后一条”,并不适合历史数据存储。

  2. 频繁更新大 Payload
    大数据量 + 高频 Retain 更新,会增加 Broker 压力。

  3. 忘记清除旧状态
    设备退役或 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 保留消息 ≠ 离线消息

🟢 它解决的是:

  • 状态同步问题
  • 新设备 / 新客户端冷启动问题

🟢 非常适合:

  • 智能家居 🏠
  • 设备状态面板 📊
  • 监控类系统 👀