使用ActiveMQ(5.14.5)作消息系统服务的场景下,
当我用Apache Qpid Proton发送消息(使用AMQP协议)发送JMS消息,用Paho MQTT接收消息的时候,
收到的消息前面总是有一串乱码,大概就是这样:
4Sp?ASr?)?x-opt-jms-destQ?x-opt-jms-msg-typeQSs?R topic://chat1@@@@@@??93-b243-fc0a073afe3
解决方案
为了方便读者快速找到解决办法,先说解决方案,
更新activemq的配置文件 $activemq_folder/conf/activemq.xml
如下图,为amqp协议连接URL增加transport.transformer=jms
指定AMQP消息到JMS消息的转换策略(conversion strategies)
重启ActiveMQ服务就OK
AMQP 映射到 JMS
有三种基本的转换策略可以与 AMQP 一起使用,实现与 JMS API 互操作。
策略 | 描述 |
---|---|
native | (默认)将 AMQP 消息的二进制数据封装到 JMS BytesMessage中,并将 AMQP 消息的标头映射到 JMS 消息上的标头。 |
raw | 将 AMQP 消息的二进制数据封装到 JMS BytesMessage中 |
jms | 将 AMQP 消息的标头映射到 JMS 消息标头,并将 AMQP 消息的正文映射到 JMS 正文。 |
通过在transportConnector上增加transport.transformer
选项设置所需的映射策略。例如,要在有效负载级别与JMS进行互操作,请将transformer选项设置为jms
:
<transportConnector name="amqp" uri="amqp://localhost:5672?transport.transformer=jms"/>
参见 ActiveMQ关于AMQP协议的官方说明
https://activemq.apache.org/components/classic/documentation/amqp《Mapping to JMS》章节
当使用默认方式时(native
)时,AMQP 消息的二进制数据封装到 JMS BytesMessage中,这进制数据库中不仅包括消息正文,还包括了保存在HashMap中的一些JMS消息的额外信息。如下图。
当在这些数据会与消息正文前面一起被序列化发送出去,就成了我们MQTT接收消息时看到的在正文前的一堆乱码。
测试代码
相关测试代码参见码云仓库:
AMQP发送单元测试:
https://gitee.com/l0km/simplemq/blob/master/simplemq-amqp/src/test/java/gu/simplemq/proton/ProtonPublisherTest.java
MQTT订阅单元测试:
https://gitee.com/l0km/simplemq/blob/master/simplemq-mqtt/src/test/java/gu/simplemq/mqtt/MqttSubscriberTest.java