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)。alarmlock 主题用于向特定设备发送命令。不过,其他订阅者也可以监听这些命令,这对于审计可能会很有用。

🔎 以 $ 开头的主题是保留的,用于消息代理内部的统计功能。通常,这种主题将以 $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/temperaturehome/front door/lockhome/alarm/enable 都会匹配上,但 beacons/bicycle/position 不会。多级通配符必须放在订阅字符串的末尾。
  • home/+/temperature - 加号是单级通配符,这里订阅了 home/garage/temperature, home/cellar/temperature 等。