主题与发布订阅模型
Topic 是 MQTT 的路由键:字符串、层级、可通配
再叠加 Retain / Will / Shared Subscription,构成完整应用语义
1. Topic 基本规则
- 使用
/分层,例如:factory/line1/robot3/joint_states - 区分大小写
- 不要以
$开头做普通业务主题($常留给系统主题,如$SYS/、$share/) - 层级为空一般应避免(如
a//b),具体以实现为准,规范有约束
1.1 设计建议(工程)
1 | {域}/{设备或服务}/{资源}/{类型} |
原则:
- 读路径即可理解含义
- 发布“状态”与“命令”分开
- 避免把巨大动态集合塞进单一巨型主题
2. 通配符(仅订阅可用)
| 通配符 | 含义 | 示例 |
|---|---|---|
+ |
单层通配 | siteA/+/battery/state |
# |
多层通配(必须是末尾) | siteA/agv07/# |
注意:
- 发布时 Topic 不能含通配符
#匹配多层,包括 0 层(视实现/规范细节,订阅设计时要小心过宽)- 过宽订阅(如
#)会压垮客户端与网络
3. 发布 / 订阅解耦
1 | Publisher ──PUBLISH──▶ Broker ──匹配订阅──▶ Subscriber(s) |
同一 Client 可同时:
- 订阅若干 Topic
- 向另一些 Topic 发布
Broker 不解析 Payload(对内容不可知),应用层自行约定 JSON / Protobuf / CDR 等。
4. 保留消息(Retain)
PUBLISH 设置 Retain=1 时:
- Broker 为该 Topic 保存最后一条保留消息
- 新订阅者一订阅匹配主题,立即收到这条保留消息(若存在)
用途:
- 设备当前状态(在线/模式/配置摘要)
- “后来的订阅者也能立刻知道现状”
清理:向同 Topic 发 空载荷 + Retain=1(常见做法)删除保留消息。
5. 遗嘱(Last Will and Testament, LWT)
在 CONNECT 时声明 Will Topic / Will Payload / Will QoS / Will Retain:
- Client 异常断线(网络中断、Keep Alive 超时等)时,Broker 代为发布 Will
- 正常 DISCONNECT 通常不触发 Will(MQTT 5 可用 Will Delay 等更精细控制)
典型用法:
1 | Will Topic: devices/agv07/status |
配合上线时 Publish {"online":true} Retain,形成在线状态机。
6. 共享订阅(Shared Subscription,MQTT 5)
形式:
1 | $share/{ShareName}/{TopicFilter} |
同一 ShareName 组内,匹配消息只投递给组内一个订阅者 → 负载均衡消费队列语义。
对比:
| 普通订阅 | 共享订阅 | |
|---|---|---|
| 同组多消费者 | 每人一份拷贝 | 组内一份、轮询/均衡 |
| 典型场景 | 状态广播 | 任务分发、日志处理 |
7. 系统主题(实现相关)
许多 Broker 提供 $SYS/# 观察连接数、流量、版本等。
非协议强制统一,以各 Broker 文档为准(Mosquitto / EMQX 各有约定)。
8. Topic 设计 Checklist
- 层级稳定、命名可读
- 命令 Topic 与状态 Topic 分离
- 订阅尽量具体,避免无脑
# - 关键状态使用 Retain + LWT
- 多消费者抢任务用 Shared Subscription(MQTT 5)
- 敏感 Topic 配合 ACL(见安全篇)
下一篇:02-控制报文与会话.md
正在加载留言…