簡介
Comet4J是一個微型的即時推送框架(類似於goeasy),它分為服務端與客戶端兩部分,你只要將服務器端(JAR文件,目前僅支持Tomcat6、7)放入WEB-INF\lib,客戶端(JavaScript文件)引入到頁面,那么你的應用就具備了向客戶端推送信息的能力,而你僅需要在服務器端調用Comet4J所提供發送方法,信息就會被主動的推送到客戶的瀏覽器上。
准備工作
下載服務端jar文件
Comet4J目前僅支持Tomcat6、7版本,根據您所使用的Tomcat版本下載【comet4j-tomcat6.jar】或【comet4j-tomcat7.jar】文件放置到WEB項目的WEB-INF\lib目錄下。
下載客戶端js文件
下載【comet4j.js】到您的項目中,比如:WebContent\js目錄下。
修改服務器配置文件
因為Comet4J工作在NIO方式下,所以我們需要調整服務器連接器配置,更換為NOI連接器。 打開server.xml文件將找到原先的連接器配置:
<Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />替換為:
<Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>
在web.xml中加載Comet4J框架
最后我們需要在web.xml配置偵聽和comet連接地址,以使Comet4J生效:
<listener>
<description>Comet4J容器偵聽</description>
<listener-class>org.comet4j.core.CometAppListener</listener-class>
</listener>
<servlet>
<description>Comet連接[默認:org.comet4j.core.CometServlet]</description>
<display-name>CometServlet</display-name>
<servlet-name>CometServlet</servlet-name>
<servlet-class>org.comet4j.core.CometServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CometServlet</servlet-name>
<url-pattern>/conn</url-pattern>
</servlet-mapping>這里是最小化配置,更多配置請參見【更多資料】。至此所有的准備工作已經就緒,現在讓我們來開發一個HelloWorld吧!
客戶端使用簡介
客戶端是一個JavaScript文件(comet4j-0.0.2.js),其中最重要的是JS.Connector和JS.Engine兩個類。JS.Connector負責與服務器建立並保持連接,而JS.Engine類負責將服務器推送過來的消息轉化為開發人員可以處理的消息事件,並分發出去,關於客戶端的API請參見:http://comet4j.axiao.org:8080/comet4j/cdoc/ 。大多數情況下,我們僅需要使用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.stop();
JS.Engine類的事件處理
上面我們介紹了如何使用start和stop方法來建立和斷開連接,當成功建立連接已后JS.Engine會發出"start"事件,當斷開后會發出“stop”事件,當收到某個通道推送過來的信息時也會發出與通道標識同名的事件。您可以事先在中使用JS.Engine.on方法來注冊事件處理函數。例如:
JS.Engine.on('start',function(cId, channelList, engine){
alert('連接已建立,連接ID為:' + cId);
});
JS.Engine.on('stop',function(cause, cId, url, engine){
alert('連接已斷開,連接ID為:' + cId + ',斷開原因:' + cause + ',斷開的連接地址:'+ url);
});
也可以將上段代碼寫成,下面代碼與上段代碼完全等效:
JS.Engine.on({
start : function(cId, channelList, engine){
alert('連接已建立,連接ID為:' + cId);
},
stop : function(cause, cId, url, engine){
alert('連接已斷開,連接ID為:' + cId + ',斷開原因:' + cause + ',斷開的連接地址:'+ url);
}
});
接下來,介紹一下如何對服務器推送過來的消息進行處理。在介紹之前,我們假設后台已經注冊了一個"hello"的應用通道標識,並且只向客戶端推送簡單的字符串信息。先看如下代碼:
JS.Engine.on('hello',function(text){
alert(text);
});
這樣當服務器端使用"hello"通道標識推送過來的消息就可以由上段代碼進行處理,將推送過來的信息彈出。
特別注意:以上代碼在事件處理函數中使用了alert僅為說明函數功能,實際使用中,在事件處理函數中切勿使用alert、prompt、confirm等可以中斷腳本運行的函數,因為Engine需要實時的保持工作狀態。
服務器端使用簡介
服務端由一個Jar包組成,其中最重的是CometContext和CometEngine兩個類。
CometContext 類
CometContext是一個單態類,通過其getInstance方法來獲得實例,它主要負責框架的一些初始化工作保存着一些參數的配置值,除此之外它還有一個更重要的職責——負責注冊應用通道標識。如果您想使用框架來實現自己的應用,那么您必需要為自己的應用分配一個唯一的通道標識,並將此通道標識在WEB容器啟動時使用CometContext的registChannel方法進行注冊,這樣,客戶端才可以正確接受此應用所推送的消息。注冊一個通道標識非常簡單:
CometContext.getInstance().registChannel("hello");
這樣便注冊了一個標識為“hello”的應用通道,而客戶也可以通過JS.Engine.on('hello',function(msg){...})的形式來接收並處理來自此通道的消息。
Comet Engine 類
另一個重要的類是CometEngine,它除了負責對連接的處理之外,對於開發人員而言,更加常用的可能是它所提供的sendTo或sendToAll方法來向客戶端發送消息:
String channel = "hello";
String someConnectionId = "1125-6634-888";
engine.sendToAll(channel , "我來了!");
engine.sendTo(channel , engine.getConnection(someConnectionId),“Hi,我是XXX”);
上面代碼使用sendToAll方法向所有客戶端在"hello"通道上發送了“我來了!”這樣一條消息,然后又使用sendTo在同樣的通道上向某一個連接發送了“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());
上面先定義了一個JoinListener並實現了父類ConnectListener的handleEvent抽像方法,然后使用engine.addConnectListener來注冊這個事件偵聽。這樣,在有客戶與服務器成功建立連接已后,就可以向此客戶端推送一條歡迎信息。
