ActiveMQ 使用Ajax 收發消息實戰

ActiveMQ 使用Ajax 收發消息實戰

 

1. 原理簡析

 

ActiveMQ 在版本發佈包中包含了web sample的demo,其中就包含js與ActiveMQ交互的庫文件amq.js.

以5.8.0版本爲例,該文件目錄爲

apache-activemq-5.8.0\webapps-demo\demo\js\amq.js這個js文件還依賴一些基於公共JavaScript框架的

適配器文件,比如依賴jQuery的適配器爲amq_jquery_adapter.js. 因此,使用amq.js時,必須先引入

jquery庫文件和適配器庫文件amq_jquery_adapter.js,然後在引入amq.js.

 

amq.js裏面提供了sendMessage方法可以發送消息到代理,而addListener和removeListener方法可以給

指定的的消息目的地添加或刪除監聽器,添加監聽器後即可接收消息了.

 

在web頁面使用sendMessage發送消息,其實是向後臺的一個servlet發送請求,然後由該servlet發送消息給代理.

這個servlet的類由ActiveMQ提供(後面配置web.xml時介紹)

 

頁面調用addListener註冊監聽器,其實也是發送請求給servlet,由servlet創建一個目的地的消費者,當該目的地

有消息時,servlet處理消息,並將消息處理響應發送給客戶端.因爲採用web的CS架構,servlet不能直接將響應發送

給客戶端. 這裏amq.js中其實是採用了一種頁面輪詢的方式向服務器請求消息,以便監聽代理上指定的目的地.

詳細信息參考ActiveMQ文檔:http://activemq.apache.org/ajax.html

 

簡而言之就是,

發送消息: amq.js使用sendMessage發送消息給servlet,servlet在將消息發給代理.

接收消息: amq.js使用addListener註冊監聽器接收並處理消息,其實也是發送請求給servlet,servlet產生消息消費者

消費指定目的地的消息併產生客戶端響應,amq.js使用一種特殊的輪詢機制不斷從服務器獲取消息處理的響應.

 

 

2.相關配置

 

本示例使用tomcat 5作爲容器,使用Maven管理工程.

 

首先使用Maven插件建立一個web工程.

 

涉及到的配置文件有兩個 web.xml和pom.xml.

 

2.1 web.xml配置,主要是配置接收客戶端請求的servlet

 

    

<servlet>
        <servlet-name>AjaxServlet</servlet-name>
        <servlet-class>org.apache.activemq.web.AjaxServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
      <servlet-name>AjaxServlet</servlet-name>
      <url-pattern>/amq/*</url-pattern>
    </servlet-mapping>

 

    

    注意這裏的<url-pattern>/amq/*</url-pattern>,配置會在amq.js發送消息時請求的servlet的rul,

    在amq.js初始化時要做響應的配置.

    

    上面<load-on-startup>1</load-on-startup>表示這個servlet在tomcat啓動時就實例化,由前面遠離

    簡析可知,這個servlet是要連接到實際的代理的,所以web.xml還提供了一個參數,用來配置這個servlet

    要連接代理的URI,配置如下,表示啓動時servlet將連接tcp://127.0.0.1:61616.

    這裏使用tcp://127.0.0.1:61616時,假如中途代理關閉了是不能自動重連的,可以使用

    failover協議,在代理從失敗中恢復時可以重連(URI使用failover://(tcp://127.0.0.1:61616)?randomize=false)

    

    

<context-param>
        <param-name>org.apache.activemq.brokerURL</param-name>
        <param-value>tcp://127.0.0.1:61616</param-value>
        <description>The URL of the Message Broker to connect to</description>
    </context-param>

 

    

    下面的配置表明 不需要啓用一個嵌入式代理

    

<context-param>
        <param-name>org.apache.activemq.embeddedBroker</param-name>
        <param-value>false</param-value>
        <description>Whether we should include an embedded broker or not</description>
    </context-param>

 

    

    下面的配置是因爲,

    因爲ajax+activemq需要servlet3.0的支持,而servlet3.0又只有在tomcat7中得到支持,

    所有加上jetty此包,就能在tomcat5,tomcat6運行了。

    (參考: http://blog.csdn.net/gongminrui8987/article/details/9446275

    另,http://blog.csdn.net/goodbaby728/article/details/8853072)

    注意,這裏使用tomcat5必須要有下面的配置,否則不能接收消息,服務器報500錯誤.

    

    

<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>

 

    

2.2 pom.xml配置

 

    這個文件注意是配置依賴到的jar包.

    

    注意配置下面兩個即可:

    

    

<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>

 

    

3. amq.js的使用

 

在index.jsp裏面點擊send按鈕發送消息給主題:topic://TEST,並註冊這個主題的監聽器.

需要注意的地方:'

(1) 需要引入三個js

  

<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>

 

  

(2)amq.js需要初始化

  

 <script type="text/javascript">
    $(document).ready(
	    function()
	    {
	      org.activemq.Amq.init(
	       { 
	         uri: 'amq', 
	         logging: true, 
	         timeout: 1, 
	         clientId:(new Date()).getTime().toString() 
	       }
	      );
	    });
    </script>

 

    上面的url就是web.xml中配置的請求URL.其他的參數含有,可以看amq.js代碼中的註釋.

    clientId是爲了在一個瀏覽器的多個頁面中使用ActiveMQ Ajax.

    詳情參考 http://activemq.apache.org/ajax.html 

    頁面的Using AMQ Ajax in Multiple Browser Windows 部分

    

 (3) 發送消息

 首先,消息的格式是格式良好的xml格式

 

var msg = "<msg type='common'>" 
              +  "<id>msg1</id>"
              +  "<content>This is test content</content>"
              + "</msg>";

 

 調用發送消息方法,點擊按鈕時,發送消息

 

$("#send").click(
    function()
    {
      amq.sendMessage("topic://TEST", msg);
    });

 

    

 (4) 接收消息

 首先,定義消息處理器:

 

var myHandler =
	{
	  rcvMessage: function(message)
	  {
	     alert(message.getAttribute('type'));
	     //console.log(message);
	  }
	};

 

然後註冊消息處理器:

amq.addListener("testHandlerId","topic://TEST",myHandler.rcvMessage);

上面的第一個參數是處理器id,可以通過將這個ID傳遞給removeListener來取消註冊.

 

注意,消息處理器中的message參數貌似是一個xml文檔格式.

使用message.getAttribute('type')這樣可以獲取屬性值.

詳細方法可以參考 ActiveMQ 版本中的chat例子.

 

4. 擴展

 

   (1)使用ActiveMQ的Ajax特性可以作爲一種實現服務器推送消息到客戶端的處理方式.

   

   (2)採用兩個消息目的地 Destination_Request和Destination_Response 可以實現請求 應答程序

   

   代理Broker_A 和 Broker_B互聯,servlet 連接到 Broker_A,

   頁面發送消息給Destination_Request,頁面監聽Destination_Response.

   

   同時有另一個系統,連接到Broker_B監聽Destination_Request,收到消息後處理消息,將消息處理

   結果發送給Destination_Response.

  

5. 遺留問題 

 

   本例在Chrome 版本 32.0.1700.76 m 運行,發送消息時,控制檯報錯:

   Refused to set unsafe header "Connection" amq_jquery_adapter.js:77

request.beforeSend amq_jquery_adapter.js:77

c.extend.ajax jquery-1.4.2.min.js:128

org.activemq.AmqAdapter.ajax amq_jquery_adapter.js:82

sendJmsMessage amq.js:183

sendMessage amq.js:276

(anonymous function) (index):67

c.event.handle jquery-1.4.2.min.js:55

j.handle.o

 

因爲這個錯,不影響功能實現,這裏選擇忽略.

 

 

 

注:附件工程中org.apache.activemq.web.AjaxServlet

和org.apache.activemq.web.MessageListenerServlet

來自ActiveMQ-web包,拷貝到這裏便於跟代碼調試.

 

 Maven版本及教程參考:  http://jackyin5918.iteye.com/blog/1945203

 myeclipse安裝Maven插件參考: http://jackyin5918.iteye.com/blog/1945929

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章