activeMQ ajax 问题小结

来源:互联网 发布:交通大学网络教育报名 编辑:程序博客网 时间:2024/05/01 17:48

          最近接手一个项目,需要实现不同项目间通讯,经过一番调研之后,决定使用activeMQ实现。于是学了activeMQ相关知识,包括activeMQ与spring集成以及activeMQ ajax实现。一开始,准备都用activeMQ与spring集成实现的,最后卡在消息接收端向前台传送消息这一步。具体来说,我实现了一个MessageListener接口,重写了OnMessage方法,最后也可以成功实现不同项目间的消息发送与接收。但是,项目本意是需要在一个项目接收到另一个项目发来的消息以后在前台弹出框提示,但接收端是在监听器的OnMessage方法中,怎样传到前端折磨了我很久,最后因为时间紧急,决定通过activeMQ与ajax结合实现前台消息接收,消息发送端仍然通过activeMQ与spring集成实现。下面说一下在activeMQ于ajax实现过程中遇到的问题:

1.因为需要用到ajax实现监听消息,所以定义了ajaxServlet,但只有servlet 3.0才支持异步机制,这在tomcat7中提供了支持。之前很多地方看到的实现代码如下:

 <servlet>        <servlet-name>AjaxServlet</servlet-name>        <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>        <load-on-startup>1</load-on-startup>    </servlet>

结果一直报 "Servlet.service() for servlet [AjaxServlet] in context with path [/activeMQ_ajax] threw exception" "java.lang.IllegalStateException: Not supported.",最后google了好久才在一个论坛里找到答案,原来是没有在AjaxServlet里提供异步支持,改为如下即可(这也许是tomcat才有的问题,在Jetty、GlassFish里可能不存在),改为如下即可:

<servlet>        <servlet-name>AjaxServlet</servlet-name>        <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>        <load-on-startup>1</load-on-startup>        <async-supported>true</async-supported>    </servlet>


2.消息发送端和接收端都实现好了,发送消息没问题,但接收端的rcvMessage函数里一直接收不到消息,但在activeMQ管理页面http://localhost:8161/admin/能够看到发送的topic以及consumer,而且message enqueued以及message dequeued都会相应的增加。各种google才得知,原来是消息头的问题:

“Be aware that, by default, messages published via Stomp which include a content-length header will be converted by ActiveMQ to binary messages, and will not be visible to your web clients. Beginning with ActiveMQ 5.4.0, you can resolve this problem by always setting the amq-msg-type header to text in messages which will may be consumed by web clients.”

解决方案:

首先,打开amq.js,由于amq.sendMessage : function(destination, message) 仅支持两个参数,没法设定发送消息的header,所以得修改amq.js中的该方法,将

sendMessage : function(destination, message) {
            sendJmsMessage(destination, message, 'send');
},

改为:

sendMessage : function(destination, message,headers) {
            sendJmsMessage(destination, message, 'send',headers);
        },
 使其支持在发送消息时设定头部。

然后,如果在发送端也是用ajax,则修改sendMessage函数如下

amq.sendMessage("topic://MyTopic","<message>Test Message</message>","amq-msg-type=>'text'");

如果是在java代码中通过Stomp等发布消息,则在创建消息以后,通过调用message.setJMSType("text")修改header为“text"类型。

参考:

http://activemq.apache.org/ajax.html

http://activemq.2283324.n4.nabble.com/AjaxServlet-on-Tomcat-td3601798.html

( to be continued )

原创粉丝点击