MQTT-主题(Topic)
Topic 介绍
MQTT 主题本质上是一个 UTF-8 编码的字符串,是 MQTT 协议进行消息路由的基础。
MQTT 主题类似 URL 路径,使用斜杠 /
进行分层。
test/a/1
test/a/b
test/+/b
test/#
- 避免歧义且易于理解,通常不建议主题以
/
开头或结尾,例如/test
或test/
- 主题不需要提前创建,订阅或发布时自动创建主题
- 无需自己创建和删除主题
主题通配符
MQTT 主题通配符包含单层通配符 +
以及 多层通配符 #
,主要用于客户端一次订阅多个主题
。
单层通配符 +
+
是用于 单个主题层级匹配的通配符
。用单层通配符时,单层通配符必须占据整个层级 。
主题 | 是否有效 |
---|---|
+ | 有效(匹配所有只有一层的主题) |
test/+ | 有效(匹配所有 test/ 开头的 两层主题 ) |
test/+/b# | 有效(匹配所有 test/ 开头 且/b 结尾 的 三层主题 ) |
test+ | 无效(+ 没有占据整个层级) |
- 若客户端订阅了主题
test/+/b
,则收到以下主题的消息
test/+/b
: 必须是三层且b是最后一层
test/1/b
test/2/b
...
test/n/b
- 匹配不到的主题
test/+/b
: 必须是三层且b是最后一层
test/b
test/a/1/b
多次通配符 #
#
是用于匹配主题中任意层级的通配符
。
- 多层通配符表示它的父级和任意数量的子层级
- 使用多层通配符时,它必须
占据整个层级
并且必须是主题的最后一个字符
主题 | 是否有效 |
---|---|
# | 有效(匹配所有主题) |
test/# | 有效(匹配所有 test/ 开头主题) |
test/b# | 无效(# 没有占据整个层级) |
test/#/b | 无效(# 不是主题最后一个字符) |
- 客户端订阅 主题
test/#
,它将会收到以下主题的消息
test
test/a
test/a/b
test/a/b/c
系统主题
以 $SYS/
开头的主题为系统主题,系统主题主要用于获取 MQTT 服务器自身运行状态
、消息统计
、客户端上下线事件
等数据。目前,MQTT 协议暂未明确规定 $SYS/
主题标准,但大多数 MQTT 服务器都遵循该标准建议。
- EMQX 服务器支持通过以下主题获取集群状态
主题 | 说明 |
---|---|
$SYS/brokers | EMQX 集群节点列表 |
$SYS/brokers/emqx@127.0.0.1/version | EMQX 版本 |
$SYS/brokers/emqx@127.0.0.1/uptime | EMQX 运行时间 |
$SYS/brokers/emqx@127.0.0.1/datetime | EMQX 系统时间 |
EMQX 还支持客户端上下线事件、收发流量、消息收发、系统监控等丰富的系统主题,用户可通过订阅 $SYS/#
主题获取所有系统主题消息。系统主题文档地址
主题 (Topic) | 说明 |
---|---|
${clientid}/connected | 上线事件。当任意客户端上线时,EMQX 就会发布该主题的消息 |
${clientid}/disconnected | 下线事件。当任意客户端下线时,EMQX 就会发布该主题的消息 |
- 订阅客户端上线的主题
# clientid 用单层通配符
$SYS/brokers/emqx@127.0.0.1/clients/+/connected
- 订阅客户端下线的主题
$SYS/brokers/emqx@127.0.0.1/clients/+/disconnected
注意
:监听系统主题需要在broker端开通对应的访问权限
# /etc/emqx/acl.conf
%% 允许任意的客户端 订阅系统主题
{allow, all, subscribe, ["$SYS/#", "#"]}.