MQTT主题、通配符和最佳实践详解(第5部分)

在 MQTT 中,主题一词是指代理用于为每个连接的客户端过滤消息的 UTF-8 字符串。主题由一个或多个主题级别组成。每个主题级别由正斜杠(主题级别分隔符)分隔。

 以下是一些主题示例:

我的家/底层/客厅/温度

美国/加利福尼亚/旧金山/硅谷

5ff4a2ce-e485-40f4-826c-b1a5d81be9b6/状态

德国/巴伐利亚/汽车/2382340923453/纬度

请注意,每个主题必须至少包含 1 个字符,并且主题字符串允许有空格。主题区分大小写。例如,myhome/temperature和MyHome /Temperature是两个不同的主题。此外,单独的正斜杠是一个有效的主题。

MQTT 通配符

当客户端订阅主题时,它可以订阅已发布消息的确切主题,也可以使用通配符同时订阅多个主题。通配符只能用于订阅主题,不能用于发布消息。有两种不同类型的通配符:单级多级

单级:+

顾名思义,单级通配符替换了一个主题级别。加号表示主题中的单级通配符。

如果主题包含任意字符串而不是通配符,则任何主题都与具有单级通配符的主题匹配。例如,订阅myhome/groundfloor/+/temperature可以产生以下结果:

多级:#

多级通配符涵盖了许多主题级别。井号表示主题中的多级通配符。为了让代理确定哪些主题匹配,多级通配符必须作为主题中的最后一个字符放置,并且前面有一个正斜杠。

 当客户端使用多级通配符订阅主题时,它会接收以通配符之前的模式开头的主题的所有消息,无论主题有多长或多深。如果您仅将多级通配符指定为主题 ( # ),您将收到发送到 MQTT 代理的所有消息。如果您期望高吞吐量,仅使用多级通配符的订阅是一种反模式(请参阅下面的最佳实践)。

以 $ 开头的主题

通常,您可以根据需要命名您的 MQTT 主题。但是,有一个例外:以 $ 符号开头的主题有不同的用途。当您将多级通配符作为主题 (#) 订阅时,这些主题不属于订阅的一部分。$-symbol 主题保留用于 MQTT 代理的内部统计信息。客户端无法向这些主题发布消息。目前,此类主题没有官方标准化。通常,$SYS/用于所有以下信息,但代理实现有所不同。$SYS-topics 的一项建议是在 MQTT GitHub wiki中。这里有些例子:

$SYS/broker/clients/已连接
$SYS/broker/clients/断开
$SYS/broker/clients/total
$SYS/broker/messages/sent
$SYS/broker/uptime

概括

这些是 MQTT 消息主题的基础知识。如您所见,MQTT 主题是动态的并且提供了极大的灵活性。在实际应用程序中使用通配符时,您应该注意一些挑战。

MQTT 最佳实践

切勿使用前导正斜杠

在 MQTT 中允许使用前导正斜杠。例如, /myhome/groundfloor/livingroom。但是,前导正斜杠引入了一个不必要的主题级别,前面有一个零字符。零没有提供任何好处,并且经常导致混乱。

切勿在主题中使用空格

空格是每个程序员的天敌。当事情没有按应有的方式进行时,空格会使阅读和调试主题变得更加困难。与前导正斜杠一样,仅仅因为某些东西是允许的,并不意味着它应该被使用。UTF-8 有许多不同的空白类型,应避免使用此类不常见的字符。

保持 MQTT 主题简短明了

每个主题都包含在使用它的每条消息中。使您的主题尽可能简短。对于小型设备,每个字节都很重要,主题长度会产生很大影响。

仅使用 ASCII 字符,避免使用不可打印的字符

由于非 ASCII 的UTF-8 字符经常显示不正确,因此很难找到与字符集相关的拼写错误或问题。除非绝对必要,否则我们建议避免在主题中使用非 ASCII 字符。

在主题中嵌入唯一标识符或客户端 ID

在主题中包含发布客户端的唯一标识符会非常有帮助。主题中的唯一标识符可帮助您识别谁发送了消息。嵌入式 ID 可用于强制授权。仅允许客户端 ID 与主题中的 ID 相同的客户端发布到该主题。例如,具有client1 ID 的客户端可以发布到client1/status,但不允许发布到client2/status

不要订阅#

有时,有必要订阅通过代理传输的所有消息。例如,将所有消息持久化到数据库中。不要使用 MQTT 客户端和订阅多级通配符来订阅代理上的所有消息。通常,订阅客户端无法处理由此方法产生的消息负载(尤其是在您有大量吞吐量的情况下)。我们的建议是在 MQTT 代理中实现扩展。例如,使用 HiveMQ 的插件系统,您可以挂钩 HiveMQ 的行为,并添加一个异步例程来处理每个传入消息并将其持久化到数据库中。

不要忘记可扩展性

主题是一个灵活的概念,无需以任何方式预先分配它们。但是,发布者和订阅者都需要了解该主题。重要的是要考虑如何扩展主题以允许新功能或产品。例如,如果您的智能家居解决方案添加了新传感器,则应该可以将它们添加到您的主题树中,而无需更改整个主题层次结构。

使用特定主题,而不是一般主题

命名主题时,不要像在队列中那样使用它们。尽可能区分您的主题。例如,如果您的客厅中有三个传感器,请为 myhome/livingroom/temperaturemyhome/livingroom/brightnessmyhome/livingroom/ humidity 创建主题。不要通过myhome/livingroom发送所有值。对所有消息使用单个主题是一种反模式。特定的命名还使您可以使用其他 MQTT 功能,例如保留消息。

物联沃分享整理
物联沃-IOTWORD物联网 » MQTT主题、通配符和最佳实践详解(第5部分)

发表评论