NIO應用之Comet4j

1、簡介

   Comet技術是服務器推技術的一個總稱,Comet被稱爲"基於HTTP長鏈接的服務器推技術",其具體實現方式是長輪詢和流。 這兩種實現方式都有一個很大的問題。請求須要在服務器上存在一段較長的時間。這使得每個請求鏈接的線程一直沒有釋放,且一直處於空閒狀態。apache

阻塞IO: 當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據徹底寫入。該線程在此期間不能再幹任何事情了。
Java NIO的非阻塞模式使一個線程從某通道發送請求讀取數據,可是它僅能獲得目前可用的數據,若是目前沒有數據可用時,就什麼都不會獲取。而不是保持線程阻塞,因此直至數據變的能夠讀取以前,該線程能夠繼續作其餘的事情。瀏覽器

2、項目實戰

2.1 準備工做

下載服務端jar文件:
  Comet4J目前僅支持Tomcat六、7版本,根據您所使用的Tomcat版本下載【comet4jtomcat6.jar】或【comet4j-tomcat7.jar】
下載客戶端js文件:
  下載【comet4j.js】到您的項目中。

修改服務器配置文件:
由於Comet4J工做在NIO方式下,因此咱們須要調整服務器鏈接器配置,更換爲NIO鏈接器。 打開server.xml文件將找到原先的鏈接器配置:tomcat

<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" 
       protocol
="org.apache.coyote.http11.Http11NioProtocol"
       redirectPort
="8443"/>

2.2 客戶端

客戶端是一個JavaScript文件(comet4j-0.0.2.js),其中最重要的是JS.Connector和JS.Engine兩個類。

JS.Connector負責與服務器創建並保持鏈接,而JS.Engine類負責將服務器推送過來的消息轉化爲開發人員能夠處理的消息事件,並分發出去,大多數狀況下,咱們僅須要使用JS.Engine類就能夠完成多數的開發工做。
JS.Engine類是一個靜態類,在一個頁面中只有一個JS.Engine類的實例。它除了負責把服務器推過來的消息轉化爲事件分發之外,與服務器的鏈接與斷開也由此類負責。

JS.Engine.start方法
JS.Engine.start(String str)和JS.Engine.stop(String str)分別控制鏈接和斷開動做,start方法須要傳入一個字符串參數,用來指定您配置的Comet4J鏈接地址。好比按前面準備工做的配置了CometServlet的地址爲/conn,那麼能夠這樣寫:服務器

JS.Engine.start('/conn');

上段代碼咱們讓瀏覽器與服務器進行鏈接,當鏈接成功之後JS.Engine類會發出"start"事件,如何進行事件的處理咱們稍後介紹。
咱們也可以讓鏈接斷開:
JS.Engine.stop('主動斷開');
上面代碼咱們讓鏈接斷開,並傳入了一個「主動斷開」這樣一個斷開的緣由。若是您並不須要對斷開的緣由進行說明,也能夠不傳遞參數: 框架

JS.Engine.stop(); 

JS.Engine類的事件處理
上面咱們介紹瞭如何使用start和stop方法來創建和斷開鏈接,當成功創建鏈接已後JS.Engine會發出"start"事件,當斷開後會發出「stop」事件,當收到某個通道推送過來的信息時也會發出與通道標識同名的事件。您能夠事先在中使用JS.Engine.on方法來註冊事件處理函數。例如:ide

JS.Engine.on({  
    start : function(cId, channelList, engine){  
      alert('鏈接已創建,鏈接ID爲:' + cId);  
    },  
    stop : function(cause, cId, url, engine){  
      alert('鏈接已斷開,鏈接ID爲:' + cId + ',斷開緣由:' + cause + ',斷開的鏈接地址:'+ url);  
    }  
});

2.3 服務器端

  服務端是CometContext和CometEngine兩個重要的類。函數

CometContext 是一個單態類,經過getInstance方法來獲取實力,它主要負責框架的一些初始化工做保存着一些參數的配置值,負責註冊應用通道標識。如戲註冊一個通道表示:url

CometContext.getInstance().registChannel("channelDemo");

  這樣便註冊了一個標識爲 channelDemo 的應用通道,二客戶也能夠經過JS.Engine.on('hello',function(msg){...})的形式來接收並處理來自次通道的信息。spa

CometEngine類線程

除了負責對鏈接的處理以外,對於開發人員而言,更加經常使用的多是它所提供的sendTo或者sendToAll方法對客戶端發送消息:

Sring channel = "channelDemo";  
String someConnectionId = "1125-6634-888";  
engine.sendToAll(channel , "我來了!");  
//發送到前段js
engine.sendTo(channel , engine.getConnection(someConnectionId),「Hi,我是XXX」); 

CometEngine也是框架工做的事件引擎的集散地,它提供了BeforeConnectEvent、BeforeDropEvent、ConnectEvent、DropEvent、MessageEvent等事件。經過對這些事件的處理來實現具體的功能:

class JoinListener extends ConnectListener {  
        @Override  
        public boolean handleEvent(ConnectEvent anEvent) {  
                CometConnection conn = anEvent.getConn();  
                CometContext.getInstance().getEngine().sendTo("hello", conn.getId(),"歡迎上線");  
        }  
}  
  
CometEngine engine = CometContext.getInstance().getEngine();  
engine.addConnectListener(new JoinListener()  
相關文章
相關標籤/搜索