多级通配符
本节介绍 MQTT 多级通配符 # 的使用方法、限制和实际应用场景。学习完成后,您将能够:
- 理解多级通配符的工作原理和使用限制
- 区分单级和多级通配符的适用场景
- 在实际项目中选择正确的通配符类型
- 避免通配符使用中的常见错误
在开始本节之前,请确保:
- 理解单级通配符
+ - 理解 Topic 层级结构
- Mosquitto Broker 已运行
Multi-Level Wildcard (#)
Section titled “Multi-Level Wildcard (#)”How It Works
Section titled “How It Works”# 通配符匹配 Topic 中剩余的所有层级(包含 0 个层级):
Topic: home/#
匹配:✅ home (# 匹配 0 层级)✅ home/livingroom✅ home/livingroom/temperature✅ home/livingroom/temperature/value✅ home/ground/kitchen/humidity
不匹配:❌ apartment/livingroom/temperature (第一层不匹配 home)Key Rules
Section titled “Key Rules”- 必须是 Topic 的最后一个字符:
#只能出现在 Topic 末尾 - 前面必须有斜杠:通常写作
/#,但单独#也有效 - 匹配所有剩余层级:包括 0 个或多个层级
- 只能用于订阅:发布者不能使用
#
Practical Examples
Section titled “Practical Examples”Example 1: 订阅整个工厂数据
Section titled “Example 1: 订阅整个工厂数据”Topic 结构:factory/{zone}/{sensor_type}/{sub_parameter}
订阅: factory/#
匹配:✅ factory (只有域)✅ factory/zone1 (域+区域)✅ factory/zone1/temperature (域+区域+类型)✅ factory/zone1/temperature/avg (域+区域+类型+子参数)# CLI 验证# 向不同层级发布mosquitto_pub -h localhost -t "factory" -m "system_online"mosquitto_pub -h localhost -t "factory/zone1" -m "zone1_ready"mosquitto_pub -h localhost -t "factory/zone1/temperature" -m "26.5"mosquitto_pub -h localhost -t "factory/zone2/humidity" -m "62"
# 使用多级通配符订阅mosquitto_sub -h localhost -t "factory/#" -v# 预期: 所有 factory 开头的 Topic 消息Example 2: 订阅设备的所有信息
Section titled “Example 2: 订阅设备的所有信息”Topic 结构:devices/{device_id}/{category}/{parameter}
订阅特定设备的所有信息:订阅: devices/esp32_001/#
匹配:✅ devices/esp32_001✅ devices/esp32_001/status✅ devices/esp32_001/temperature/current✅ devices/esp32_001/temperature/history/last_hour✅ devices/esp32_001/humidity/currentExample 3: 监控整个系统
Section titled “Example 3: 监控整个系统”// Node-RED 中使用多级通配符监控全局// 订阅所有消息(危险做法 - 可能收到大量消息)msg.topic = "#"; // 订阅 Broker 上的所有 Topic
// 更合理的做法:订阅特定域的全局msg.topic = "factory/#"; // 只关注工厂数据Comparison: + vs #
Section titled “Comparison: + vs #”| 发布 Topic | 订阅 home/+ | 订阅 home/# |
|---|---|---|
home | ❌ (+ 必须匹配一个层级) | ✅ (# 匹配0层级) |
home/livingroom | ✅ | ✅ |
home/livingroom/temperature | ❌ (层级数不同) | ✅ |
home/livingroom/temperature/value | ❌ | ✅ |
你需要订阅: │ ├── 某个层级下的所有数据(不限深度) │ └── 使用 # │ 例: factory/# │ ├── 某个特定层级的所有值(限定深度) │ └── 使用 + │ 例: factory/zone1/+ │ ├── 组合需求 │ └── 多个 + 或 + 与 # 组合 │ 例: factory/+/temperature/# (所有区域温度下的所有子数据) │ └── 全局所有消息 └── 单独 # 例: # (慎用,可能收到大量消息)Advanced Patterns
Section titled “Advanced Patterns”Mixed Wildcard Usage
Section titled “Mixed Wildcard Usage”+ 和 # 可以在同一个订阅中组合使用:
订阅: factory/+/temperature/#
匹配:✅ factory/zone1/temperature (区域1温度)✅ factory/zone1/temperature/current (区域1当前温度)✅ factory/zone2/temperature (区域2温度)✅ factory/zone2/temperature/avg (区域2平均温度)✅ factory/zone2/temperature/history (区域2历史温度)
不匹配:❌ factory/zone1/humidity (传感器类型不匹配)❌ office/zone1/temperature (域不匹配)# 组合通配符 CLI 验证# 发布数据mosquitto_pub -h localhost -t "factory/zone1/temperature" -m "26.5"mosquitto_pub -h localhost -t "factory/zone1/temperature/current" -m "26.5"mosquitto_pub -h localhost -t "factory/zone2/temperature" -m "28.0"mosquitto_pub -h localhost -t "factory/zone1/humidity" -m "62" # 不会被接收
# 订阅mosquitto_sub -h localhost -t "factory/+/temperature/#" -vReal-World Use Cases
Section titled “Real-World Use Cases”Use Case 1: 运维监控仪表板
Section titled “Use Case 1: 运维监控仪表板”// 监控特定工厂区域的所有数据// 在 Node-RED 中使用[ { "topic": "factory/zone1/#", "description": "订阅 Zone1 的所有数据" }, { "topic": "factory/zone2/alarm/#", "description": "订阅 Zone2 的所有告警" }]Use Case 2: 设备调试接口
Section titled “Use Case 2: 设备调试接口”// 调试工具:查看特定设备的所有 Topicfunction subscribeToDevice(deviceId) { const topic = `devices/${deviceId}/#`; mqttClient.subscribe(topic); console.log(`Monitoring all topics for device: ${deviceId}`);}Common Pitfalls
Section titled “Common Pitfalls”Pitfall 1: # 不在末尾
Section titled “Pitfall 1: # 不在末尾”❌ 错误订阅: home/#/temperature 原因: # 必须是 Topic 最后一个字符
✅ 正确订阅: home/#✅ 正确订阅: #Pitfall 2: # 前缺少斜杠
Section titled “Pitfall 2: # 前缺少斜杠”✅ 正确: factory/# 意义: factory 下的所有子层级
✅ 正确: # 意义: 全局所有 Topic
注意: 单独 `#` 是有效的全局通配符Pitfall 3: 使用 # 发布消息
Section titled “Pitfall 3: 使用 # 发布消息”❌ 错误: mosquitto_pub -t "home/#" -m "data" Error: Wildcard not allowed in publish
✅ 正确: mosquitto_pub -t "home/livingroom/temperature" -m "26.5"Performance Considerations
Section titled “Performance Considerations”# 通配符的性能影响
Section titled “# 通配符的性能影响”使用 # 通配符,尤其是在系统级使用,需要注意性能影响:
风险:- 订阅 # 会收到 Broker 上的所有消息- 如果系统中有大量 Topic,可能导致消息泛滥- 设备消息和系统消息都收到(如 $SYS 消息)
建议:✅ 限定域范围: factory/# 优于 #✅ 结合 + 精确控制: factory/zone1/# 优于 factory/#✅ 使用排除规则: 通过 ACL 过滤不需要的 Topic验证多级通配符
Section titled “验证多级通配符”# 完整测试
# 1. 订阅多级通配符mosquitto_sub -h localhost -t "factory/#" -v &
# 2. 发布不同层级的消息mosquitto_pub -h localhost -t "factory" -m "init"mosquitto_pub -h localhost -t "factory/zone1" -m "active"mosquitto_pub -h localhost -t "factory/zone1/temperature" -m "26.5"mosquitto_pub -h localhost -t "factory/zone1/temperature/avg" -m "26.3"mosquitto_pub -h localhost -t "factory/zone2/humidity" -m "62"
# 预期: 收到所有 5 条消息Summary
Section titled “Summary”本节要点总结:
#通配符:匹配 Topic 中剩余的所有层级(含 0 层)- 使用限制:必须是 Topic 末尾,只能用于订阅
+vs#:+匹配一个层级,#匹配多个层级- 组合使用:
+和#可以在一个订阅中组合 - 性能注意:
#订阅范围广,应限定域范围避免消息泛滥