新闻中心
深入理解MQTT主题通配符:多级通配符#的使用限制与规范解析

本文详细解析mqtt主题订阅中多级通配符`#`的使用规则与限制。根据mqtt规范,`#`字符必须作为主题过滤器的最后一个字符,不能在其后跟随其他主题层级。文章通过实例代码演示了合法与非法的`#`使用场景,并解释了为何`a/#/b`等形式的订阅会引发`valueerror`,而单级通配符`+`或位于末尾的`#`则有效,旨在帮助开发者避免常见的订阅错误,确保mqtt通信的正确性。
在MQTT(Message Queuing Telemetry Transport)协议中,主题(Topic)是消息路由的核心机制。为了实现灵活的消息订阅,MQTT引入了通配符(Wildcards)的概念,主要包括单级通配符+和多级通配符#。然而,这两种通配符的使用并非没有限制,特别是多级通配符#,其规范要求尤为严格。本文将深入探讨#通配符的使用规范,并通过具体示例解析常见的订阅错误。
MQTT主题通配符概述
MQTT定义了两种特殊字符用于构建主题过滤器:
单级通配符 (+): +号用于匹配主题层级中的单个层级。例如,sport/+/player 可以匹配 sport/tennis/player 和 sport/football/player,但不能匹配 sport/tennis/match/player。+可以出现在主题过滤器的任何位置,只要它代表一个完整的层级。
多级通配符 (#): #号用于匹配主题中任意数量的层级,包括零个层级(即匹配其父级)。它是最强大的通配符,但其使用规则也最为严格。
多级通配符#的核心规范
根据MQTT v3.1.1规范(4.7.1.2 Multi-level wildcard),多级通配符#的使用有着明确的限制:
The number sign (‘#’ U+0023) is a wildcard character that matches any number of levels within a topic. The multi-level wildcard represents the parent and any number of child levels. The multi-level wildcard character MUST be specified either on its own or following a topic level separator. In either case it MUST be the last character specified in the Topic Filter [MQTT-4.7.1-2]
这条规范的核心在于:多级通配符#必须是主题过滤器中的最后一个字符。 这意味着#之后不能再有任何主题层级或层级分隔符/。它既可以单独使用(如#,匹配所有主题),也可以跟在主题层级分隔符之后(如A/#)。
paho-mqtt订阅错误解析
在实际开发中,如果违反了上述规范,使用paho-mqtt库进行订阅时,通常会遇到ValueError: Invalid subscription filter.的错误。以下通过具体示例来解释为何会出现这类错误以及正确的用法。
无效的多级通配符使用示例
考虑以下尝试订阅多个主题的代码,其中包含不符合规范的多级通配符:
import paho.mqtt.client as mqtt
client = mqtt.Client()
# ... 连接到MQTT Broker ...
# 尝试订阅包含不合规多级通配符的主题
invalid_topics = [('A/#/B', 1), ('A/#/C', 1), ('A/#/D', 1)]
try:
client.subscribe(invalid_topics)
print("订阅成功 (这不应该发生,除非环境不同)")
except ValueError as e:
print(f"订阅失败: {e}")
# 输出: 订阅失败: Invalid subscription filter.上述代码会引发ValueError: Invalid subscription filter.,因为A/#/B中的#后面跟着了/B。这违反了#必须是主题过滤器最后一个字符的规范。MQTT Broker或客户端库在解析时会认为这是一个无效的主题过滤器。
有效的通配符使用示例
对比之下,以下是符合MQTT规范的通配符订阅示例:
1. 单级通配符 (+) 的使用:
Reachout.ai
一个AI驱动的视频开发平台,专为忙碌的企业家和销售团队打造
142
查看详情
单级通配符可以出现在主题路径的中间,因为它只匹配一个层级。
import paho.mqtt.client as mqtt
client = mqtt.Client()
# ... 连接到MQTT Broker ...
# 订阅包含单级通配符的主题
valid_single_level_topics = [('A/+/B', 1), ('A/+/C', 1), ('A/+/D', 1)]
try:
client.subscribe(valid_single_level_topics)
print("成功订阅单级通配符主题。")
except ValueError as e:
print(f"订阅失败: {e}")这段代码会成功执行,因为A/+/B中的+符合规范,它匹配A和B之间的任意一个层级。
2. 多级通配符 (#) 作为最后一个字符:
当#位于主题过滤器的末尾时,它是完全合法的。
import paho.mqtt.client as mqtt
client = mqtt.Client()
# ... 连接到MQTT Broker ...
# 订阅多级通配符在末尾的主题
valid_multi_level_topic = 'A/#'
try:
client.subscribe(valid_multi_level_topic)
print("成功订阅多级通配符在末尾的主题。")
except ValueError as e:
print(f"订阅失败: {e}")这段代码也会成功执行。A/#将匹配所有以A/开头的主题,例如A/B、A/B/C,甚至A(如果#匹配零个层级)。
更多规范示例(来自MQTT规范的非规范性注释)
为了进一步巩固理解,我们来看一些来自MQTT规范的额外示例:
- sport/#:有效,匹配sport及其所有子主题(如sport/tennis、sport/football/player)。
- #:有效,匹配所有应用消息。
- sport/tennis/#:有效,匹配sport/tennis及其所有子主题。
- sport/tennis#:无效,#前没有层级分隔符/。#必须单独使用或紧跟在/之后。
- sport/tennis/#/ranking:无效,#后面跟着了/ranking。
总结与注意事项
通过上述分析,我们可以得出关于MQTT多级通配符#使用的关键原则:
- #必须是主题过滤器的最后一个字符。 这是最核心的规则,任何在其后跟随其他字符(包括/)的用法都是无效的。
- #可以单独使用 (#) 或紧跟在层级分隔符之后 (A/#)。
- 单级通配符+则可以在主题路径的任意层级使用,只要它代表一个完整的层级。
在设计MQTT主题结构时,理解并严格遵守这些通配符规则至关重要。如果您的应用场景确实需要匹配类似A/任意层级/B这样的模式,您可能需要重新考虑主题设计,或者订阅更宽泛的主题(如A/#),然后在客户端代码中对接收到的消息进行进一步过滤
。遵循MQTT规范不仅能避免订阅错误,还能确保不同MQTT客户端和Broker之间互操作性的一致性。
以上就是深入理解MQTT主题通配符:多级通配符#的使用限制与规范解析的详细内容,更多请关注其它相关文章!
# 信中
# 建设隧道招工信息网站
# 金华建设网站找哪家
# seo优化排名关键词
# 昭通抖音营销推广怎么样
# 韶关建设局网站
# 什么网站建设公司最好
# 深圳专业专业网站建设
# 小米手机seo
# 黄冈网站建设服务有什么
# 江门牛肉粉团购网站推广
# 路由
# 图像处理
# 着了
# 这段
# 它是
# 客户端
# 出现在
# 分隔符
# 连接到
# 跟在
# win
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Win11怎么设置鼠标指针速度_Win11提高鼠标指针精确度选项
解决 Express.js 中 PUT 请求密码修改失败的路由配置指南
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧
苹果手机指南针不准怎么校准 传感器校准方法详解【建议收藏】
必由学网页版入口 必由学官方平台直接访问
内存疯狂猛猛涨价:主板销量直接腰斩!
深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现
Odoo 16:在表单视图中基于当前记录动态修改Tree视图属性
动漫花园资源网使用步骤_动漫花园资源网下载流程
c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架
如何在CSS中使用visited与link控制链接颜色_visited link伪类配合
J*aScript中高效清空DOM列表元素:解决for循环中断与任务管理问题
html两个JS只运行一个怎么办_让双JS在html中都运行方法【技巧】
Win11输入法不见了怎么办_Windows11恢复语言栏显示方法
Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达
b站怎么取消点赞_b站点赞取消操作方法
J*a TimerTask中HashMap意外清空的深层原因与解决方案
Android Studio计算器C键功能异常排查与修复教程
飞书妙记怎样用语音转文字速记_飞书妙记用语音转文字速记【速记方法】
优化大型XML文件解析:基于Python流式处理的内存高效方案
在J*a项目里如何构建对象之间的契约_接口约束的实际落地
使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战
Lar*el Excel导入时生成自定义递增ID的策略与实践
如何创建独立于主系统的J*a运行环境_隔离式环境搭建策略
Sublime Text怎么显示空格和制表符_Sublime显示不可见字符设置
Yandex免登录网页版地址 Yandex搜索引擎官方访问入口
Win11截图该按哪些键 Win11截屏完整流程解析【教程】
俄罗斯浏览器官网直达链接 俄罗斯浏览器最新在线入口导航
Python字典中优雅地迭代剩余元素的方法
机构:以往存储涨价周期小米利润率实际上有所改善 能转嫁给消费者等
React列表渲染与独立状态管理:避免全局状态影响局部更新
俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口
Gmail邮箱申请注册直达_Gmail邮箱免费注册PC版官网入口2025
css卡片内容溢出如何处理_使用overflow隐藏或scroll显示内容
响应式图片在网页设计中的正确实现方法
win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】
Python实时数据流中的动态最值查找策略
C++ vector二维数组定义_C++ vector of vector用法
提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案
html怎么运行外部js文件中的函数_运html外js文件函数法【技巧】
天眼查怎么看公司融资情况 天眼查企业融资历史查询步骤【攻略】
微信网页版官方入口直达 微信网页版网页版登录使用方法
台积电1.4nm工艺A14瞄准2028:10年来性能提升80%
MAC怎么让Dock栏只显示当前运行的应用_MAC终端命令实现极简Dock栏
mcjs网页版在线存档 mcjs云存档登录入口
Win10双系统截图高效法 截屏快捷键速记【技巧】
Kafka Streams中基于消息头条件过滤消息的实现指南
Win10系统怎么查看已安装更新_Win10卸载有问题的更新补丁


2025-11-14
浏览次数:次
返回列表