MQTT 是如何工作的
⚠️ 本节练习需要一个 MQTT 服务器。如果你参加了 Ferrous Systems 的培训,培训中将会提供一个登录凭证,用于访问 Espressif 运营的服务器。否则,你可以使用 https://test.mosquitto.org/ 中列出的 MQTT 服务器,或者在本地安装一个。
作为入门教程的收尾,让我们向开发板添加一些 IoT 功能。 我们的目标是让板子发送实时更新的传感器值,而无需像使用 HTTP 服务器时那样反复查询。此外,还可以让板子接收命令,更改 LED 的颜色。
这些内容可以使用发布-订阅架构进行建模。多个客户端在特定的频道/主题上发布消息,同时可以订阅这些主题,来接收其他设备发布的消息。这些消息的分发由消息代理(broker)协调——在本例中,就是 MQTT 服务器。
MQTT 消息
MQTT 消息由两部分组成——主题(topic)和 payload。
主题的作用与电子邮件中的主题,或文件柜上的标签相同。而 payload 包含实际的数据。payload 数据的格式没有规定,最常见的是 JSON。
🔎 最新版本的 MQTT 标准(MQTT 5)支持内容的类型元数据。 发送 MQTT 消息时,需要指定一个服务质量(QoS),表示这个消息会被传输:
- 最多一次。
- 至少一次。
- 恰好一次。
对于本练习,选择哪种服务质量并不重要。
MQTT 主题
MQTT 主题是表示层次结构的 UTF-8 字符串,各个层次由斜杠 /
分隔。支持前导斜杠,但不推荐。这里是一些例子:
home/garage/temperature
beacons/bicycle/position
home/alarm/enable
home/front door/lock
在这里,一个传感器会定期发布车库温度(home/garage/temperature),并广播给每个订阅者。自行车信标发布 GPS 坐标也是一样(beacons/bicycle/position)。alarm
和 lock
主题用于向特定设备发送命令。不过,其他订阅者也可以监听这些命令,这对于审计可能会很有用。
🔎 以 $
开头的主题是保留的,用于消息代理内部的统计功能。通常,这种主题将以 $SYS
开头。客户端不能向这些主题发布消息。
⚠️ 由于所有本教程的参与者会共享同一个 MQTT 服务器,因此需要采取一些措施来防止串扰。本练习的框架会为每一个签出的仓库,生成一个唯一且随机的 ID(采用 UUID v4
格式)。你也可以在线手动生成一个。在电脑和开发板之间传输消息时,你的 UUID 应该用作主题的前导部分。大致上类似于这种模式:
6188eec9-6d3a-4eac-996f-ac4ab13f312d/sensor_data/temperature
6188eec9-6d3a-4eac-996f-ac4ab13f312d/command/board_led
订阅主题
客户端发送订阅消息以表示他们希望接收某些主题下的消息。通配符的支持是可选的。通配符可以用于匹配单个或多个层次。
home/garage/temperature
- 只订阅这个特定的主题home/#
- 井号是多级通配符,因此它订阅了以home/
开头的所有主题。home/garage/temperature
、home/front door/lock
和home/alarm/enable
都会匹配上,但beacons/bicycle/position
不会。多级通配符必须放在订阅字符串的末尾。home/+/temperature
- 加号是单级通配符,这里订阅了home/garage/temperature
,home/cellar/temperature
等。