cometd簡單用例


准備工作

整個例子的源碼下載:http://pan.baidu.com/s/1gfFYSbp

下載服務端jar文件

Comet4J目前僅支持Tomcat6、7版本,根據您所使用的Tomcat版本下載【comet4jtomcat6.jar】或【comet4j-tomcat7.jar】文件放置到WEB項目的WEB-INF\lib目錄下。

本文下載comet4j-tomcat7.jar, 下載地址:http://pan.baidu.com/s/1eSBXmfS

下載客戶端js文件

下載【comet4j.js】到您的項目中,比如:WebContent\JS\cometd目錄下。
下載地址:http://pan.baidu.com/s/1qXYxkYg
 

修改服務器配置文件

因為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"/>  

客戶端

我們利用Comet4J開發一個每隔一秒向所有客戶端推送一個定時增長的數字。
 
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Cometd首頁</title>
<script type="text/javascript" src="./JS/cometd/comet4j.js"></script>
<script type="text/javascript">

    var projectPath = '<%= request.getContextPath()%>';
    function cometdCallback(text){
        var kbDom = document.getElementById('num1');
        kbDom.innerHTML = text;
    }
    function init() {

        JS.Engine.on({
            number : cometdCallback
        });
        JS.Engine.start(projectPath+'/conn');

    }
</script>
</head>
<body onload="init()">
    數字3:
    <span id="num1">...</span>
</body>
</html>

 

其中,<%=request.getContextPath()%>是為了解決相對路徑的問題,可返回站點的根路徑。

服務端

package com.cvicse.ump.cometd;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.comet4j.core.CometContext;

public class CometdTestClass implements ServletContextListener {
    
    private static final String CHANNEL_NUM = "number";
    private static int number = 0;

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {

    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
        CometContext.getInstance().registChannel(CHANNEL_NUM);
        Thread timeThread = new Thread(new TimeThread(),"numTimeThread");
        timeThread.setDaemon(true);//設置為守護線程
        timeThread.start();
    }
    
    class TimeThread implements Runnable{

        @Override
        public void run() {
            while(true){
                CometContext.getInstance().getEngine().sendToAll(CHANNEL_NUM, number++);
                System.out.println(CHANNEL_NUM+": "+number);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
            }
            
        }
        
    }

}

配置

web.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>cometd</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
  
  <listener>
      <description>Comet4J容器偵聽</description>
      <listener-class>org.comet4j.core.CometAppListener</listener-class>
  </listener>
  
  <listener>
      <listener-class>com.cvicse.ump.cometd.CometdTestClass</listener-class>
  </listener>
  
  <servlet>
      <description>Comet連接[默認:org.comet4j.core.CometServlet]</description>  
      <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>
  
</web-app>

 

至此,已經完成,啟動Tomcat,就可以訪問了,能看到每隔5秒鍾,數字漲1;
整個例子工程源碼,下載路徑:http://pan.baidu.com/s/1gfFYSbp
 

客戶端使用簡介

客戶端是一個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.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兩個類。

Comet Context 類

CometContext是一個單態類,通過其getInstance方法來獲得實例,它主要負責框架的一些初始化工作保存着一些參數的配置值,除此之外它還有一個更重要的職責——負責注冊應用通道標識。如果您想使用框架來實現自己的應用,那么您必需要為自己的應用分配一個唯一的通道標識,並將此通道標識在WEB容器啟動時使用CometContext的registChannel方法進行注冊,這樣,客戶端才可以正確接受此應用所推送的消息。注冊一個通道標識非常簡單
 
CometContext.getInstance().registChannel("hello");  
這樣便注冊了一個標識為“hello”的應用通道,而客戶也可以通過JS.Engine.on('hello',function(msg){...})的形式來接收並處理來自此通道的消息。

Comet Engine 類

另一個重要的類是CometEngine,它除了負責對連接的處理之外,對於開發人員而言,更加常用的可能是它所提供的sendTo或sendToAll方法來向客戶端發送消息:
 
ring 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來注冊這個事件偵聽。這樣,在有客戶與服務器成功建立連接已后,就可以向此客戶端推送一條歡迎信息。

Comet4J配置參數表

 
<!--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>  
<!-- Comet4J可選參數配置-->  
<context-param>  
        <description>語言[支持:zh,en,默認:zh,詳細http://www.loc.gov/standards/iso639-2/php/English_list.php]</description>  
        <param-name>Comet.Language</param-name>  
        <param-value>zh</param-value>  
</context-param>  
<context-param>  
        <description>請求超時時間/微妙[默認:60000,1分鍾,建議至少設置3秒以上]</description>  
        <param-name>Comet.Timeout</param-name>  
        <param-value>60000</param-value>  
</context-param>  
<context-param>  
        <description>連接空閑過期時間/微妙[默認:5000,5秒]</description>  
        <param-name>Comet.ConnExpires</param-name>  
        <param-value>5000</param-value>  
</context-param>  
<context-param>  
        <description>連接檢查頻率/微妙[默認:5000,5秒]</description>  
        <param-name>Comet.ConnFrequency</param-name>  
        <param-value>5000</param-value>  
</context-param>  
<context-param>  
        <description>緩存信息過期時間/微妙[默認:60000,1分種]</description>  
        <param-name>Comet.CacheExpires</param-name>  
        <param-value>60000</param-value>  
</context-param>  
<context-param>  
        <description>緩存信息過期檢查頻率/微妙[默認:60000,1分種]</description>  
        <param-name>Comet.CacheFrequency</param-name>  
        <param-value>60000</param-value>  
</context-param>  
<context-param>  
        <description>連接模式[auto(默認)/stream/lpool]</description>  
        <param-name>Comet.WorkStyle</param-name>  
        <param-value>auto</param-value>  
</context-param>  
<context-param>  
        <description>開啟調試[false(默認)/true]</description>  
        <param-name>Comet.Debug</param-name>  
        <param-value>false</param-value>  
</context-param>  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM