0

我有一个关于 Paho 订阅的问题,以及应用程序如何管理不同的主题(允许使用通配符)。我们之所以感兴趣,是因为我们提供了一个层来管理所有这些东西,以简化开发人员的生活,因此如果需要,我们以后可以在后台使用非 MQTT 发布/订阅。

一个例子可能是最好的解释方式。假设我们的程序中有两个独立的模块:

  • get_all_info()短时间订阅主题fleet/vehicle-N/#以获取特定车辆的所有信息N
  • speed_mon()fleet/+/speed,仅对所有车辆的速度感兴趣,在程序期间订阅。

考虑序列(a)

  • speed_mon()订阅fleet/+/speed.
  • get_all_info()订阅fleet/vehicle-17/#并获取信息。
  • get_all_info()取消订阅fleet/vehicle-17/#

第三次操作会影响第一次吗?换句话说,我们还会收到 topic 的消息fleet/vehicle-17/speed吗?

如果取消订阅是对特定订阅的简单撤销,它将仅禁用在第二个要点中创建的订阅。

如果它使用过滤器禁用所有匹配的订阅(在通配符的意义上),它也会影响第一个订阅。


(a)现在忽略这样一个事实,即我们最好在程序期间订阅并且永远不要取消订阅,而只是将消息缓存到本地存储中get_all_info()fleet/#这是一个人为的例子。我们无法控制客户如何使用我们的层。

4

1 回答 1

1

我相信 MQTT 规范对此非常清楚。v3v5文本相似;v3 状态:

UNSUBSCRIBE 数据包中提供的主题过滤器(无论它们是否包含通配符)必须逐个字符地与服务器为客户端保存的当前主题过滤器集进行比较。如果任何过滤器完全匹配,则删除其拥有的订阅,否则不会发生额外处理 [MQTT-3.10.4-1]。

所以这是一个字符一个字符的比较;取消订阅fleet/vehicle-17/#不会影响订阅fleet/+/speed

请注意,在将传入消息映射到回调时,某些库可能无法正确实现这一点(go 库曾经有这个错误)。

也许一个更有趣的问题是(你没有问这个,但它可能会产生影响):

如果我订阅了两者fleet/+/speed,我会收到关于该主题fleet/vehicle-17/#的多个消息副本。fleet/vehicle-17/speed

这里的行为在 v3 ( spec )中更受实现细节的影响,但由于订阅标识符 ( spec ) 的引入,在 v5 中明确定义。

于 2021-08-19T01:39:21.920 回答