背景:在做某类程序应用时,需要将服务器的响应自动的反馈给浏览器,而不是采用用户请求的方式。基于这样的应用还是比较多的,比如说网页聊天、实时消息提醒等等。所以我们需要这样一种技术来实现服务器主动的将信息推送到浏览器。
先准备需要的工具: comet4j-tomcat6.jar(tomcat6的就导入这个) comet4j-tomcat7.jar(tomcat7的就导入这个) comet4j.js(页面引入这个js)
修改下tomcat的server.xml文件把protocol参数值改成下面的,因为这是基于nio开发的插件
接着配置下项目web.xml
<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>/comet</url-pattern> </servlet-mapping> <listener> <description>TestComet</description> <listener-class>com.shadow.extras.comet4j.TestComet</listener-class> </listener>配置工作完; 接下来进行简单的使用: 1.页面端代码:
<!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="js/comet4j.js"></script> <script type="text/javascript"> function init(){ var number1 = document.getElementById('number1'); var number2 = document.getElementById('number2'); // 建立连接,conn 即web.xml中 CometServlet的<url-pattern> JS.Engine.start('conn'); // 监听后台某个频道 JS.Engine.on( { // 对应服务端 “频道1” 的值 result1 result1 : function(num1){ number1.innerHTML = num1; }, // 对应服务端 “频道2” 的值 result2 result2 : function(num2){ number2.innerHTML = num2; }, } ); } </script> </head> <body onload="init()"> 数字1:<span id="number1">...</span><br></br> 数字2:<span id="number2">...</span> </body> </html> 2.后端推送工具类: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.comet4j.core.CometConnection; import org.comet4j.core.CometContext; import org.comet4j.core.CometEngine; import org.comet4j.core.event.ConnectEvent; import org.comet4j.core.listener.ConnectListener; import com.Comet; public class CometUtil extends ConnectListener implements ServletContextListener { /** * 初始化上下文 */ public void contextInitialized(ServletContextEvent arg0) { // CometContext : Comet4J上下文,负责初始化配置、引擎对象、连接器对象、消息缓存等。 CometContext cc = CometContext.getInstance(); // 注册频道,即标识哪些字段可用当成频道,用来作为向前台传送数据的“通道” cc.registChannel(Constant.CHANNEL_MSGCOUNT); cc.registChannel(Constant.CHANNEL_MSG_DATA); //添加监听器 CometEngine engine = CometContext.getInstance().getEngine(); engine.addConnectListener(this); } @Override public void contextDestroyed(ServletContextEvent sce) { // TODO Auto-generated method stub } @Override public boolean handleEvent(ConnectEvent connEvent){ // TODO Auto-generated method stub final CometConnection conn = connEvent.getConn(); Object userId = conn.getRequest().getSession().getAttribute("currentUserId"); CacheManager.putContent(userId.toString(), connEvent); return true; } private void doCache(final CometConnection conn,String userId) { if (userId != null) { CacheManager.putContent(conn.getId(), String.valueOf(userId), Constant.EXPIRE_AFTER_ONE_HOUR); } /** * 推送给所有的客户端 * @param comet */ public void pushToAll(Comet comet){ try { CometEngine engine = CometContext.getInstance().getEngine(); //推送到所有客户端 engine.sendToAll(Constant.CHANNEL_MSGCOUNT,comet.getMsgCount()); engine.sendToAll(Constant.CHANNEL_MSG_DATA,comet.getMsgData()); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } } /** * 推送给指定客户端 * @param comet */ public void pushTo(Comet comet){ try { ConnectEvent connEvent = (ConnectEvent) CacheManager.getContent(comet.getUserId()).getValue(); final CometConnection conn = connEvent.getConn(); //建立连接和用户的关系 doCache(conn,comet.getUserId()); final String connId = conn.getId(); CometEngine engine = CometContext.getInstance().getEngine(); if (CacheManager.getContent(connId).isExpired()) { doCache(conn,comet.getUserId()); } //推送到指定的客户端 engine.sendTo(Constant.CHANNEL_MSGCOUNT, engine.getConnection(connId), comet.getMsgCount()); engine.sendTo(Constant.CHANNEL_MSG_DATA, engine.getConnection(connId), comet.getMsgData()); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } }