ActiveMQ中MQTT消息话题名符号映射问题

当使用ActiveMQ充当消息Broker时,如使用MQTT协议的客户端订阅发布ActiveMQ消息则会遇到一个ActiveMQ消息话题名和MQTT消息话题名映射的问题,在ActiveMQ官网的MQTT支持文档 中也提到了此问题,但是对于这个话题名符号映射在新老版本的ActiveMQ中的处理还是有差异存在,下面将详细说明。

官方支持文档的说明

Working with Destinations with MQTT


MQTT supports hierarchies and wildcards, though the delimiters and characters are different: - Here’s the mapping:

function ActiveMQ MQTT
separator . /
element * +
sub tree > #

These values are automatically transposed between clients using JMS/NMS/Stomp and clients using MQTT. For example - a client subscribing to “foo/#/bar” would receive messages published on a JMS Topic of foo.blah.bar.

蹩脚的翻译

使用MQTT协议的客户端工作

MQTT支持层级分隔符和通配符,但是与传统ActiveMQ消息的不同:-这是映射表:

功能 ActiveMQ MQTT
分隔符 . /
元素通配符 * +
子结构 > #

这些值(指上述分隔符和通配符)会在使用JMS/NMS/Stop协议的客户端和使用MQTT协议的客户端的消息传输过程中自动转换。例如-当一个采用MQTT协议的客户端订阅“foo/#/bar”这个话题的消息时将会收到以JMS话题“foo.blah.bar”发布的消息。

新旧版本ActiveMQ对上述映射处理的差异

正常情况下,在使用MQTT协议的客户端订阅发布消息话题用到上述分隔符和通配符的情况下,应该使用“/”、“+”和“#”这三个来订阅发布对应的JMS消息的话题名,如官方文档中提到的示例一样。在这种情况下,从不论是开始支持MQTT协议客户端的最早的ActiveMQ版本还是最新版本,上述映射没有任何差异。但是当使用MQTT协议的客户端订阅发布消息话题,使用的分隔符和通配符是“.”、“*”和“>”时,新旧版本的ActiveMQ对映射的处理却有如下不同。

以订阅话题foo.blah.bar为例:


  1. ActiveMQ老版本(5.9.0及以下,5.9.X无法下载故未验证,理论上所有5.9版本均存在该问题)当MQTT客户端订阅的话题名为“foo.blah.bar”时,其实际订阅的ActiveMQ话题即为“foo.blah.bar”,即不对话题中的分隔符和通配符做映射转化。

  2. ActiveMQ新版本(5.10.X版本),当MQTT客户端订阅的话题名为“foo.blah.bar”时,其实际订阅的ActiveMQ话题即为“foo\blah\bar”,即会对话题中的分隔符和通配符做映射转化。

综上及建议

如果想消除ActiveMQ新老版本对消息话题中分隔符和通配符映射的差异,则最好采用官方推荐的方式,即MQTT的客户端订阅发布消息时话题中使用“/”、“+”和“#”等符号,JMS消息客户端订阅发布消息时话题中使用“.”、“*”和“>”等符号。