MQTT (Paho) 中不同订阅规则是否会产生冲突?
Paho MQTT 通配符订阅取消规则解答
直接结论
按照MQTT 3.x/5.0协议规范,以及Eclipse Paho客户端的默认实现,第三步取消fleet/vehicle-17/#订阅的操作不会影响第一个fleet/+/speed的订阅,你依然可以正常收到fleet/vehicle-17/speed主题的消息。
核心逻辑说明
MQTT协议的订阅、取消订阅动作都是基于用户提交的精确主题过滤器字符串匹配,不是基于通配符反向匹配已有的订阅规则:
- 客户端内部会维护一个独立的订阅过滤器列表,每个调用订阅接口传入的过滤器都会作为独立条目存储,互相之间没有关联
- 调用取消订阅接口时,只会删除列表中和传入的过滤器完全相等的条目,不会遍历所有已有订阅删除匹配该过滤器的其他规则
对应场景的订阅列表变化
你给出的执行序列对应的内部订阅列表变化如下:
speed_mon()完成订阅后,列表为:["fleet/+/speed"]get_all_info()完成订阅后,列表新增条目:["fleet/+/speed", "fleet/vehicle-17/#"]- 取消
fleet/vehicle-17/#订阅后,只会删除完全匹配的第二个条目,剩余列表为:["fleet/+/speed"],fleet/vehicle-17/speed依然满足剩余的过滤器规则,消息会正常投递。
统一管理层开发建议
如果你们要封装支持跨底层组件的统一Pub/Sub管理层,需要注意:
- 不要自行实现“取消订阅时删除所有匹配该过滤器的订阅”的逻辑,这不符合MQTT的行业默认行为,会导致上层业务逻辑异常
- 建议为每个订阅动作生成独立的唯一订阅ID,取消订阅时优先支持通过订阅ID精确撤销,这样不管底层是MQTT还是其他非MQTT Pub/Sub组件,行为完全一致,不会出现歧义,也能更好地兼容上层业务的使用习惯。
注(a):本回答基于你给出的示例场景讨论,不涉及具体业务实现的优化方案,默认兼容上层业务任意的订阅/取消订阅使用方式。
内容的提问来源于stack exchange,提问作者paxdiablo
相关产品推荐
相关产品推荐

