首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MQTT通信的核心:Topic主题

MQTT通信的核心:Topic主题

作者头像
Hello工控
发布2025-12-17 20:03:51
发布2025-12-17 20:03:51
2820
举报
文章被收录于专栏:Hello工控Hello工控

我们前面几期重点介绍了MQTT的定义、MQTT发布和订阅架构,以及重要的Message类型详细解说。

我们这期重点介绍MQTT 的灵活性和效率的核心,即两个关键概念:主题Topic和通配符Wildcards。这些功能构成了 MQTT 发布/订阅模型的基础,使得在复杂的物联网生态系统中实现无缝且有针对性的通信成为可能。

MQTT 主题作为消息的地址机制,允许设备和应用程序组织和过滤信息流。它们提供了一种层次结构,可以表示您的物联网系统中的各种方面,从设备位置到传感器类型和数据类别。了解如何有效地设计和利用主题对于创建可扩展且易于管理的物联网解决方案至关重要。

与主题互补的是 MQTT 通配符,这些强大的工具增强了协议的灵活性。通配符允许订阅者同时从多个主题接收消息,简化客户端逻辑并减少网络开销。通过掌握通配符,开发人员可以创建更动态和响应式的物联网应用,能够适应不断变化的数据需求而无需不断重新配置。

接下来我们将深入探讨 MQTT 主题和通配符的复杂性,探索它们的结构、最佳实践和高级功能。

什么是Topic主题?

Topic主题指的是一个 UTF-8 字符串,用于过滤连接客户端的消息。主题由一个或多个级别组成,级别之间用正斜杠分隔(主题级别分隔符)。以下是如何为家中办公室的灯创建一个主题的例子:

需要注意的是:主题是区分大小写的,因此这两个主题是不同的:

如果您想通过 MQTT 在家庭办公室中打开一盏灯,可以想象以下场景:

  1. 一个设备在 home/office/lamp 主题上发布“on”和“off”消息。您有一个控制灯的设备(可以是 ESP32、ESP8266 或其他任何板子或设备)。
  2. 控制您灯的 ESP32 订阅了相同的主题:home/office/lamp
  3. 因此,当该主题发布新消息时,ESP32 会接收到“开”或“关”消息并控制灯的开关。

使用Topic最佳的实践指南

以下最佳实践支持创建一个清晰结构化的 MQTT 主题层次结构,这是可扩展的工业统一命名空间(UNS)架构的基础。

1

确保清晰

明确的主题对于确保 MQTT 客户端和代理之间的顺畅数据传输至关重要。清晰且无歧义的主题命名可以防止冲突并促进工业生态系统内的顺畅互操作性。注意:MQTT 主题是区分大小写的。这意味着 x/yX/y 被视为两个不同的主题。

2

工厂之间的标准化

整个公司的主题结构需要保持一致。这种结构应该适用于所有设施、生产线和机器。同时,可以通过引入专门用于特殊用例的主题来考虑不同组织层级的个别需求,例如 enterprise/site/area/workCell/individual

3

粒度 vs. 模块化

在粒度和模块化之间取得良好的平衡至关重要。粒度或模块化的决策应基于您的用例需求。

  • 粒度使个体数据点的详细映射成为可能,例如在特定主题.../temperature 中的温度值。这使得以有针对性的方式订阅特定事件和数据变得更加容易。
  • 模块化将多个数据点组合到一个共同的主题中,这支持了 MQTT 命名空间的清晰性和可扩展性。例如,所有传感器数据,如温度、压力和湿度,可以一起发布到 .../sensor 主题中。

4

分层组织

主题结构应反映一个明确定义的层次结构,该层次结构反映了您的工业生态系统中的物理和逻辑结构。主题的树状组织使得可以在较高层次放置更广泛的类别(例如“工厂”或“生产线”),并在其下方放置更具体的主题(例如“订单”或“传感器数据”)。这提供了几个优势:

  • 清晰度:良好的结构化层次使得在 MQTT 命名空间中理解和导航更加容易。
  • 灵活性:新的主题可以轻松集成到现有结构中,而不破坏一致性。
  • 效率:客户端可以订阅较高层次的广泛数据概览或较低层次的非常具体的信息。

5

上下文相关的命名

使用清晰且有意义的主题名称,明确传达上下文和目的。经过深思熟虑、具有上下文意义的命名可以让用户更容易理解每个主题的内容和功能,减少潜在的误解。这增加了易用性并提高了 MQTT 命名空间内的清晰度。

示例:而不是使用 .../data ,可以使用 .../machine1/status 以提供更精确的信息。这可以清楚地表明内容,而无需额外的文档说明。

6

集成版本控制

随着 MQTT 命名空间随着时间的推移而演变,建议将版本控制集成到 MQTT 主题层次结构中。这使得管理变更更加容易,并确保向后兼容。版本控制允许引入新结构而不影响现有系统。版本控制的集成示例 v1/.../areaID/lineID/cellIDmySpec/v1/.../areaID/lineID/cellID

7

其他建议

  • 避免将主题名称弄得过长以提高可读性。
  • 不要使用 MQTT 特定的字符,如 #、+、/ 和 $,因为这些字符在 MQTT 协议中有特殊功能。主题不应以 / 开头或结尾,例如 /chatchat/
  • 应避免使用空格,因为它们可能会导致混淆或在某些系统中引起问题。
  • 只使用 ASCII 字符,不要使用任何不可打印字符。
  • 不要使用 # 订阅所有主题。
  • 使用 _- 来连接主题级别内的单词(或驼峰式写法)。
  • 尽量使用较少的主题层级。
  • 尽量在消息数据模式中建模以避免使用通配符主题。
  • 当使用通配符时,尽量将更独特的主题层级移向根部。比如, device/00000001/command/#device/command/00000001/# 更好。

MQTT 主题在 MQTT 客户端和代理之间建立通信中至关重要。它们可以根据消息内容实现高效的过滤和路由。在 MQTT 基础系统中确保有效数据交换和处理的关键在于正确定义和结构化主题

图片
图片

MQTT通配符

MQTT中,通配符提供了一种强大的机制,可以同时订阅多个主题。当客户端订阅一个主题时,它可以订阅发布的消息的确切主题,或者使用通配符来扩展其订阅范围。需要注意的是,通配符只能用于订阅,而不能用于发布消息。有两种类型的通配符: single-levelmulti-level

MQTT 通配符 – 单层通配符: +

单级通配符由加号(+)表示,允许替换一个主题级别。通过订阅包含单级通配符的主题,任何包含通配符位置处任意字符串的主题都将匹配。

例如,订阅 myhome/groundfloor/+/temperature 可能会产生以下结果:

MQTT 通配符 – 多级:

多级通配符可以覆盖多个主题级别。它由井号符号 (#) 表示,并且必须作为主题中的最后一个字符出现,前面跟一个斜杠。

当客户端订阅带有多级通配符的主题时,它会接收到所有以通配符字符前的模式开始的主题的消息,无论主题的长度或深度如何。如果主题仅指定为“#”,则客户端将接收到发送到 MQTT 代理的所有消息。

需要注意的是预期比较大的主题量,订阅广泛的主题会导致大量消息被发送到客户端,这可能会对系统性能和带宽使用产生影响。遵循上一节最佳实践来优化主题订阅,避免不必要的消息过载。

以 $ 开始的MQTT主题

在 MQTT 中,主题命名的灵活性很大,允许您选择适合您需求的主题名称。但是,需要注意一个重要的例外情况:以 符号开头的主题有其特殊用途。这些主题在使用多级通配符 (#) 作为主题时不会包含在订阅中。相反,以 开头的主题是保留给 MQTT 代理的内部统计信息的,提供了对其操作的有价值见解。

开头的主题发布消息是不允许的,因为这些主题用于 MQTT 代理向客户端暴露内部信息和统计信息。虽然目前这些主题没有官方标准化,但通常会使用前缀 SYS/ 来表示此类信息,尽管不同实现的代理可能会有所不同。

以下是一些$SYS相关的主题说明:

共享订阅是 MQTT 5.0 的一个特性,是一种在多个订阅者之间实现负载均衡的订阅方法。共享订阅的主题以$share 开头。

在以下示意图中,三个订阅者使用共享订阅方法订阅了同一个主题 share/g/topic ,其中 topic 是他们实际订阅的真实主题名称,而发布者向 topic 发布消息,但不向 share/g/topic 发布消息。

MQTT主题常见问题

Q:MQTT 主题的最大层级和长度是多少?

A: MQTT 主题是 UTF-8 编码的字符串,必须不超过 65535 字节。然而在实践中,使用更短的主题名称和更少的层级意味着更少的资源消耗。

尽量不要因为“我可以”就使用更多的主题层级。

例如, my-home/room1/datamy/home/room1/data 更好。

Q:每个主题的数量有限制吗?

A: 不同的消息服务器对主题的数量有不同的限制。但主题越多,服务器内存的使用量也会越大。鉴于连接到 MQTT 代理的设备数量众多,我们建议客户端订阅不超过十个主题。

Q:通配符订阅会降低性能吗?

A: 当将消息路由到通配符订阅时,代理可能需要比非通配符主题更多的资源。如果可以避免通配符订阅,这是一个明智的选择。

这在很大程度上取决于 MQTT 消息负载中的数据模型。例如,如果发布者发布到 device-id/stream1/foodevice-id/stream1/bar ,而订阅者需要订阅这两个主题,那么它可能订阅 device-id/stream1/# 。更好的替代方案可能是将 foo 和 bar 部分的命名空间推送到负载中,这样它只发布到一个主题 device-id/stream1 ,而订阅者只需订阅这个主题即可。

Q:正常主题和通配符主题的重叠订阅如何接收消息?

A: 例如,如果一个客户端同时订阅了 #test 主题,当发布到 test 时,它是否会收到两条重复的消息?这取决于 MQTT 代理的实现。有些会为每个匹配的订阅发送消息,因此可能会出现重复。但是,用户可以利用 MQTT 5.0 订阅标识符来区分消息来源,并基于标识符在客户端处理这些重复消息。

Q:我能否使用共享订阅和普通订阅订阅同一个主题?

A: 但是不推荐这样做。根据 MQTT 规范,多个订阅会导致消息重复交付。

参考链接:

  1. https://randomnerdtutorials.com/what-is-mqtt-and-how-it-works/
  2. https://www.emqx.com/en/blog/advanced-features-of-mqtt-topics
  3. https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
  4. https://i-flow.io/en/ressources/mqtt-topic-namespace-best-practices-step-by-step-guide/
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Hello工控 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是Topic主题?
    • 明确的主题对于确保 MQTT 客户端和代理之间的顺畅数据传输至关重要。清晰且无歧义的主题命名可以防止冲突并促进工业生态系统内的顺畅互操作性。注意:MQTT 主题是区分大小写的。这意味着 x/y 和 X/y 被视为两个不同的主题。
    • 随着 MQTT 命名空间随着时间的推移而演变,建议将版本控制集成到 MQTT 主题层次结构中。这使得管理变更更加容易,并确保向后兼容。版本控制允许引入新结构而不影响现有系统。版本控制的集成示例 v1/.../areaID/lineID/cellID 或 mySpec/v1/.../areaID/lineID/cellID 。
  • MQTT 通配符 – 单层通配符: +
  • Q:MQTT 主题的最大层级和长度是多少?
  • Q:通配符订阅会降低性能吗?
  • Q:正常主题和通配符主题的重叠订阅如何接收消息?
  • Q:我能否使用共享订阅和普通订阅订阅同一个主题?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档