ActiveMQ(四)———Ajax调用

一、背景

使用aciveMQ最多的场景就是服务器端向客户端推送消息,当然这里的服务器+客户端合起来组成了消费者或者生产者,不要理解成客户端成了消费者,服务器端成了生产者。activeMQ使用ajax来监听服务器端推送的消息主要是用到了一种特殊的轮询保持机制。一般的轮询就是间隔一段时间向服务器请求数据,此时服务器会立马给出应答。而轮询保持则是向服务器发送了请求(包括等待时间比如20秒),服务器接受到请求之后会立马查询消息队列是否有数据,有就立马返回,没有的话这个请求就进入阻塞状态,唤醒时间设置为20秒。20秒之后发现数据则立马返回,否则20秒结束之内再返回,此时客户端(浏览器)会再发起另一个请求。这样占用的服务器资源较少,但是达到了实时的目的。

二、服务器端配置

Web.xml

当客户端向服务器发送请求时,都会请求到这个servlet
<servlet>
    <servlet-name>AjaxServlet</servlet-name>
    <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>AjaxServlet</servlet-name>
    <url-pattern>/amq/*</url-pattern>
</servlet-mapping>
MQ的部署地址,用于服务器端访问消息队列
<context-param>
     <param-name>org.apache.activemq.brokerURL</param-name>
     <param-value>tcp://127.0.0.1:61616</param-value>
</context-param>
因为ajax+activemq需要servlet3.0的支持,而servlet3.0又只有在tomcat7中得到支持,所以加上jetty此包,就能在tomcat5,tomcat6运行了。
<!-- 兼容tomcat7.0以下 -->
<filter>  
   	<filter-name>session</filter-name>  
   	<filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>  
</filter>  
<filter-mapping>  
    <filter-name>session</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping> 

Pom.xml

<dependency>
    		<groupId>org.apache.activemq</groupId>
     	<artifactId>activemq-all</artifactId>
     	<version>5.8.0</version>
   </dependency>
   <dependency>
     	<groupId>org.apache.activemq</groupId>
     	<artifactId>activemq-web</artifactId>
     	<version>5.8.0</version>
   </dependency>
   <dependency><!-- 兼容tomcat7.0以下 -->
    <groupId>org.eclipse.jetty.aggregate</groupId>
    <artifactId>jetty-all-server</artifactId>
    <version>7.6.7.v20120910</version>
</dependency>

三、客户端(浏览器)配置

1、引入js文件,jquery.js类库支持,amq_jquery_adapter.js封装amq的ajax和log方法,amq是消息交互处理的核心文件。

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/amq_jquery_adapter.js"></script>
<script type="text/javascript" src="js/amq.js"></script>

2、初始化请求参数

var amq = org.activemq.Amq;
  amq.init({ 
    uri: '/amq', 
    logging: true,
    timeout: 20,
    clientId:"123"
    //clientId:(new Date()).getTime().toString()
  });

Uri表示浏览器请求服务器端时的地址
Logging表示浏览器在与服务器端交互时是否打印js日志
Timeout表示轮询保持的时间
Clientid表示浏览器的身份,如果用同一个字符串,则只有一个窗口会生效;如果用时间做参数,那么每一个浏览器窗口就相当于不同的消费者。

3、获取消息之后回调函数处理

var myHandler ={
    rcvMessage: function(message){
    	console.log(message.data);
    	console.log(message.nodeValue);
    	console.log(message.wholeText);
    	//var bidData = eval('('+ message.textContent+ ')');
    }
  };

这个函数是接收到消息之后的回调函数,至于回调函数的参数是一个js对象,取值的方法根据字符串和xml格式还不一样。最好的方式就是先研究一下amq.js的源代码,下面我直接给出不同的格式不同的取值方法。
消息队列中的消息是xml格式<ds><dd>xml格式1</dd><ss>xml格式2</ss></ds>
Message.nodeName = “ds”
Message.childNodes[0].nodeName = “dd”
Message.childNodes[0].textContent= “xml格式1”
Message.childNodes[1].nodeName = “ss”
Message.childNodes[1].textContent= “xml格式2”
消息队列中的消息是json格式"{'firstName':'Bill' , 'lastName':'Gates' }"
Message.data= "{'firstName':'Bill' , 'lastName':'Gates' }",这里data、nodeValue、wholeText、textContent均可取值。

4、客户端监听和发送消息

amq.addListener('topic_js','topic://topic_js2',myHandler.rcvMessage);
amq.sendMessage(myDestination,myMessage);

浏览器向服务器端发送注册监听器和发送消息的请求。
topic_js表示消费者的一个ID,接受到消息回调时会用到作为标识
topic://topic_js2表示目的地,也可以为queue
myHandler.rcvMessage表示回调函数


最后附上一段查看源码之后的总结,具体的奥秘还是需要自己去体会,收获会很大。

首先服务器端启动的时候如果设置的自动启动<load-on-startup>1</load-on-startup>,那么就会初始化这个AjaxServlet并调用它的init方法。Init方法里面包含了ConnectionFactory的初始化。当客户端调用init()方法之后会不断给服务器发送请求,请求的保持时间是20秒。一旦收到服务器的响应之后,会解析里面的数据,如果有对应数据则判断客户端是否注册回调函数,有则会调用回调函数,否则抛出异常。当请求第一次到达服务器时,会根据sessionId+clientId组装成AjaxWebClient,这个AjaxWebClient包含了对应的监听器以及消费者,会立马获取一次消息,如果没有消息则会让这个请求挂起20秒,并且将这个异步挂起状态传递给监听器,当这个监听器收到ActiveMQ的消息时,会唤醒这个挂起的请求,然后进一步组装消息用来响应客户端。如果20秒之内,监听器都没有收到消息,那么这个请求会自动被唤醒,然后设置返回状态码为200,以及返回一些基本的数据给客户端,客户端会解析这个数据,发现没有想要的数据就不会调用回调函数,继续发起下一个请求。调用addListener,会向服务器发送一个POST请求,会组装和GET请求一样的AjaxWebClient,会根据topic://topic_js2来生成对应的Topic或者QUEUE,名称为topic_js2。然后会判断这个请求是要干嘛,当请求参数里面包含listen时,会创建一个消费者并且绑定监听事件,监听消息队列。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值