Comet4J(Comet for Java)是一個純粹基於AJAX(XMLHTTPRequest)的服務器推送框架,消息以JSON方式傳遞,具有長輪詢、長鏈接、自動選擇三種工做模式。javascript
Tomcat六、Tomcat7html
支持XMLHTTPRequest對象的瀏覽器都可支持長輪詢工做模式,但不必定可以支持長鏈接。java
瀏覽器/平臺 | 版本 | 長輪詢 | 長鏈接 |
Internet Explorer | 6,7,8,9 | √ | X |
FireFox | 3.0+(更底版本未知) | √ | √ |
Chrome | 7.0+(更底版本未知) | √ | √ |
Safari | 5+(更底版本未知) | √ | √ |
Opera | 11.10+(更底版本未知) | √ | X |
Air | 1.5+(更底版本未知) | √ | √ |
IOS(Iphone/Ipad) | 3.1+(更底版本未知) | √ | √ |
Android | 未測試 | 未知 | 未知 |
BlackBerry | 未測試 | 未知 | 未知 |
Comet4J使用web
1.下載依賴apache
comet4j.js https://code.google.com/p/comet4j/downloads/detail?name=comet4j.js
comet4j-tomcat7.jar https://code.google.com/p/comet4j/downloads/detail?name=comet4j-tomcat7.jar瀏覽器
2. 配置tomcat緩存
修改server.xml(注意:若不修改則會報 405)tomcat
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>服務器
改成app
<Connector connectionTimeout="20000" port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443" />
將comet4j-tomcat7.jar放在tomcat的lib下
3.服務端實現
新建類TestComet4j實現ServletContextListener接口,實現服務端主動推送消息到客戶端。
package cn.slimsmart.comet.demo; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.comet4j.core.CometContext; import org.comet4j.core.CometEngine; /** * 服務端主動推送消息到客戶端 */ public class TestComet4j implements ServletContextListener { // 頻道1 private static final String CHANNEL1 = "channel1"; // 頻道2 private static final String CHANNEL2 = "channel2"; // 經過頻道1推送給前臺的變量1 private static int number1 = 0; // 經過頻道2推送給前臺的變量2 private static int number2 = 100; /** * 初始化上下文 */ public void contextInitialized(ServletContextEvent servletContextEvent) { // CometContext : Comet4J上下文,負責初始化配置、引擎對象、鏈接器對象、消息緩存等。 CometContext cc = CometContext.getInstance(); // 註冊頻道,即標識哪些字段可用當成頻道,用來做爲向前臺傳送數據的「通道」 cc.registChannel(CHANNEL1); cc.registChannel(CHANNEL2); Thread myThread = new Thread(new SendToClientThread(), "SendToClientThread"); // 下面的內部類的方法是個死循環,設置helloAppModule線程爲「守護線程」,則當jvm只剩「守護線程」時(主線程結束),該線程也會結束。 myThread.setDaemon(true); // 開始線程 myThread.start(); } /** * 內部類線程類 */ class SendToClientThread implements Runnable { public void run() { while (true) { try { Thread.sleep(1000); } catch (Exception ex) { ex.printStackTrace(); } // CometEngine : 引擎,負責管理和維持鏈接,並可以必要的發送服務 CometEngine engine = CometContext.getInstance().getEngine(); // 參數的意思:經過什麼頻道(CHANNEL1)發送什麼數據(number1++),前臺可用可用頻道的值(result1)來獲取某頻道發送的數據 engine.sendToAll(CHANNEL1, number1++); engine.sendToAll(CHANNEL2, number2++); } } } /** * 銷燬 */ public void contextDestroyed(ServletContextEvent servletContextEvent) { } }
配置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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>comet-demo</display-name> <!-- 配置監聽器 監聽咱們本身的類 --> <listener> <listener-class>org.comet4j.core.CometAppListener</listener-class> </listener> <listener> <description>testComet4j</description> <listener-class>cn.slimsmart.comet.demo.TestComet4j</listener-class> </listener> <!-- 客戶端訪問的入口 --> <servlet> <servlet-name>CometServlet</servlet-name> <servlet-class>org.comet4j.core.CometServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CometServlet</servlet-name> <url-pattern>/push</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>
4.客戶端實現
新建index.html,並將comet4j.js放在同一目錄下。
index.html經過js實踐消息監聽:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Comet4J Hello World</title> <script type="text/javascript" src="comet4j.js"></script> <script type="text/javascript"> function init(){ var number1 = document.getElementById('number1'); var number2 = document.getElementById('number2'); // 創建鏈接,push 即web.xml中 CometServlet的<url-pattern> JS.Engine.start('push'); // 監聽後臺某個頻道 JS.Engine.on( { // 對應服務端 「頻道1」 的值 channel1 channel1 : function(num1){ number1.innerHTML = num1; }, // 對應服務端 「頻道2」 的值 channel2 channel2 : function(num2){ number2.innerHTML = num2; }, } ); } </script> </head> <body onload="init()"> 數字1:<span id="number1">...</span><br></br> 數字2:<span id="number2">...</span> </body> </html>
5.運行結果:
代碼下載: