本文共 8344 字,大约阅读时间需要 27 分钟。
eclipse(Version: Helios Service Release 2Build id: 20110218-0911 )
1.一个全新的tomcat:E:\Tomcat7-MQ 2.新建一个Dynamic Web Project:MQAjax 3.创建文件 <webapp-root>/META-INF/context.xml. 参考: <Context antiJARLocking="true"> name="jms/ConnectionFactory" type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS Connection Factory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" brokerURL="tcp://localhost:61616" brokerName="LocalActiveMQBroker" useEmbeddedBroker="false"/> <Resource name="jms/topic/MyTopic" type="org.apache.activemq.command.ActiveMQTopic" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="MY.TEST.FOO"/> <Resource name="jms/queue/MyQueue" type="org.apache.activemq.command.ActiveMQQueue" factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="MY.TEST.FOO.QUEUE"/> </Context>
4.并将web.xml文件头替换为支持servlet3.0,3.0才能支持异步机制: <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="true"> 在WEB-INF\web.xml中加入以下servlet配置,注意必须开启异步支持
<async-supported>true</async-supported>: <servlet-name>AjaxServlet</servlet-name> <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class> <async-supported>true</async-supported> <servlet-name>AjaxServlet</servlet-name> <url-pattern>/amq/*</url-pattern> <param-name>org.apache.activemq.brokerURL</param-name> <param-value>tcp://localhost:61616</param-value> geronimo-j2ee-management_1.1_spec-1.0.1.jar geronimo-jms_1.1_spec-1.1.1.jar geronimo-jta_1.0.1B_spec-1.0.1.jar activemq-client-5.8.0.jar jetty-all-server-7.6.7.v20120910.jar 6. 在<webapp-root>下新建页面index.html,<head></head>中加入: <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/amq_jquery_adapter.js"></script>
<script type="text/javascript" src="js/amq.js"></script>
<script type="text/javascript">
var amq = org.activemq.Amq;
7.在<webapp-root>下新建js目录,将apache-activemq-5.8.0\webapps-demo\demo\js下的三个js文件拷贝到js目录中: 8.接下来启动Tomcat,不会报错,并且在ActiveMQ的管理界面能看到多了一个consumer 注意,默认情况下,通过Stomp发布的消息如果包含了content-length消息头,则它将会被ActiveMQ转换为二进制消息,并且会对web客户端不可见。从ActiveMQ 5.4.0开始,你可以通过将amq-msg-type消息头 设置设为“text”,以使消息可以被web客户端消费。
message.setJMSType("text");
控制面板(右上角选择查看方式为大图标)---防火墙---高级设置---高级设置---出站规则/出站规则
11.发现还是有问题,但是没有日志没法调试,现在解决log4j的问题 servlet支持:eclipse中,项目名称右键--properties--targeted runtime,把tomcat7勾上。
12.遇到Tomcat启动问题,并由于该问题造成Ajaxservlet运行不正常(这个问题卡了老子好久啊啊啊啊啊啊啊!!!!) 在eclipse中启动tomcat,tomcat一直处于starting状态,导致程序运行不正常,servlet运行不正常等现状。
在排除了端口冲突,防火墙之类的问题之后,实在没辙最后一招,
在Servers窗口中删除现有的Tomcat,然后重建一个,在没有加入任何程序时测试,Tomcat顺利启动到started状态,停止后加入web工程,再次启动Tomcat,顺利进入started状态!
13.目前遇到问题,message被页面接收后无法显示 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); amq.sendMessage("topic://FirstTopic","<message>"+ms+"</message>","amq-msg-type=>'text'"); 这样修改后,通过页面发送的消息,就能在页面中显示了。
目前的index.html源码如下,该页面实现了一个简单的多人聊天室,注意接收到的消息要用
message.text :
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/amq_jquery_adapter.js"></script> <script type="text/javascript" src="js/amq.js"></script> <div style="height:400px;width:600px;border:block;overflow:auto" id="msg"> <script type="text/javascript"> var amq = org.activemq.Amq; rcvMessage: function(message) //alert("received data:"+message.text); document.getElementById("msg").innerHTML += message.text + "<br>"; amq.addListener("smeguangdong","topic://FirstTopic",myHandler.rcvMessage); var nickname = document.getElementById("nickname").value; var content = document.getElementById("keymsg").value; var ms = nickname + " : " +content; amq.sendMessage("topic://FirstTopic","<message>"+ms+"</message>","amq-msg-type=>'text'"); <input type="text" id="nickname"> <input type="text" id="keymsg"> <button onclick="go()">submit</button> </html> 在IE中用
message.text可以成功显示收到信息;在CHROME中用
message.textContent可以成功显示收到信息,没有一种方式可以兼容多浏览器??
1.
ActiveMQ的Ajax插件自动把消息内容解释成了DOM格式,也就是说Listener回调函数中的message参数是DOM结构的,更有意思的是如果像这样一个消息:“<message>aaa</message><message>bbb</message>”,那么Listener回调函数会执行两次,因为里面包含了两个Element,如果是这样的消息:“<message>aaa</message>asdfasdfaksd”, Listener回调函数也会执行两次,““<message>aaa</message>”是Element,而“asdfasdfaksd”是Text。
2.而用java代码TextMessage message = session.createTextMessage("MSG sent from java 2");创建的消息,就是字符串文本形式。 了解了原理后就简单了,用js操作dom的方法来解析收到的信息即可,以inde.html页面可以
兼容多浏览器,兼容web发送消息和java发送消息两种场景的消息接收:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript" src="js/jquery-1.4.2.min.js"></script> <script type="text/javascript" src="js/amq_jquery_adapter.js"></script> <script type="text/javascript" src="js/amq.js"></script> <div style="height:400px;width:600px;border:block;overflow:auto" id="msg"> <script type="text/javascript"> var amq = org.activemq.Amq; rcvMessage: function(message) //alert("received data:"+message.text); //alert("message.textContent :"+message.textContent) //alert("message.childNodes.item(0).nodeValue:"+message.childNodes.item(0).nodeValue) 兼容IE和CHROME //alert("message.childNodes[0].nodeValue:"+message.childNodes[0].nodeValue); 兼容IE和CHROME if(message.childNodes.length > 0) //web页面发送的消息 document.getElementById("msg").innerHTML += message.childNodes[0].nodeValue + "<br>"; document.getElementById("msg").innerHTML += message.nodeValue + "<br>"; amq.addListener("smeguangdong","topic://FirstTopic",myHandler.rcvMessage,{selector:"user='liyang'"}); //amq.addListener("smeguangdong","topic://FirstTopic",myHandler.rcvMessage); var nickname = document.getElementById("nickname").value; var content = document.getElementById("keymsg").value; var ms = nickname + " : " +content; amq.sendMessage("topic://FirstTopic","<message>"+ms+"</message>","amq-msg-type=>'text'"); <input type="text" id="nickname"> <input type="text" id="keymsg"> <button onclick="go()">submit</button> </html> 一旦支持了selector,我们就可以实现指定用户的实时消息提醒了!!!(可以通过java代码发送指定属性的消息,web接收时指定selector过滤条件即可) 官方文档已经提到 : 在添加监听器时指定第三个参数即可实现接收消息时的过滤。
amq.addListener( myId,
myDestination, myHandler.rcvMessage,
{ selector:"identifier='TEST'" } );
这样的话通过jsp标签之类的技术,
在渲染页面时将参数渲染为当前登录用户名即可实现根据当前登录用户过滤消息的目的。
至此为止,已经实现了在页面中通过指定destination(topic/queue)和selector来接受消息,基本已经满足实时消息提醒的需求(消息由java程序发送,指定)。 转载地址:http://xbcgi.baihongyu.com/