Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询、长连接、自动选择三种工作模式。
客户端API
服务端API
功能特性
- 推送消息广播。
- 推送定向消息。
- 提供连接上线前、上线、下线前、下线、发送消息等多种可处理事件。
- 消息缓存机制,确保长轮询工作模式下不丢失消息。
- 客户端正常下线,服务端可立即感知。
- 客户端异常停止工作,服务端可定时检查并感知。
- 以注册通道应用的方式,让开发者对框架功能进行扩展,实现自己的应用。
框架特性
- 独立小巧,不依赖于第三方包。
- 与应用紧密集成,无需独立应用或服务器。
- 与Session无关的连接机制,为开发人员提供最大程度的功能可控性。
- 面向事件编程,客户端与服务器端均为事件驱动开发模式,提供了良好的可扩展性机制。
- 各项性能参数均可配置。
- 支持多种主流浏览器,并支持Air应用环境。
服务器支持情况
Tomcat6、Tomcat7
浏览器支持情况
支持XMLHTTPRequest对象的浏览器均可支持长轮询工作模式,但不一定能够支持长连接。
浏览器/平台 | 版本 | 长轮询 | 长连接 |
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 | 未测试 | 未知 | 未知 |
项目地址:https://code.google.com/p/comet4j/ (google,国内无法访问)
Comet4J使用
1.下载依赖
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
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
改为
<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.jsp</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 οnlοad="init()">
数字1:<span id="number1">...</span><br></br>
数字2:<span id="number2">...</span>
</body>
</html>
5.运行结果:
浏览器debug: