利用Comet4J 及时推送消息
简介
Comet4J是一个微型的即时推送框架,它分为服务端与客户端两部分,你只要将服务器端(JAR文件,目前仅支持Tomcat6、7)放入WEB-INF\lib,客户端(JavaScript文件)引入到页面,那么你的应用就具备了向客户端推送信息的能力,而你仅需要在服务器端调用Comet4J所提供发送方法,信息就会被主动的推送到客户的浏览器上。
准备工作
下载服务端jar文件
Comet4J目前仅支持Tomcat6、7版本,根据您所使用的Tomcat版本下载【comet4jtomcat6.jar】或【comet4j-tomcat7.jar】文件放置到WEB项目的WEB-INF\lib目录下。
下载客户端js文件
下载【comet4j.js】到您的项目中,比如:WebContent\js目录下。
修改服务器配置文件
因为Comet4J工作在NIO方式下,所以我们需要调整服务器连接器配置,更换为NOI连接器。 打开server.xml文件将找到原先的连接器配置:
[html] view plaincopy
- <Connector executor="tomcatThreadPool" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
替换为:
[html] view plaincopy
- <Connector URIEncoding="UTF-8" connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>
客户端
我们利用Comet4J开发一个每隔一秒向所有客户端推送服务器的剩余内存大小。 helloworld.html
[html] view plaincopy
- <!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-0.0.2.js"></script>
- <script type="text/javascript">
- function init(){
- var kbDom = document.getElementById('kb');
- JS.Engine.on({
- hello : function(kb){//侦听一个channel
- kbDom.innerHTML = kb;
- }
- });
- JS.Engine.start('conn');
- }
- </script>
- </head>
- <body onload="init()">
- 剩余内存:<span id="kb">...</span>KB
- </body>
- </html>
服务端
helloworld.java
[java] view plaincopy
- package org.comet4j.demo.helloworld;
- import javax.servlet.ServletContextEvent;
- import javax.servlet.ServletContextListener;
- import org.comet4j.core.CometContext;
- import org.comet4j.core.CometEngine;
- public class HelloWorld implements ServletContextListener {
- private static final String CHANNEL = "hello";
- public void contextInitialized(ServletContextEvent arg0) {
- CometContext cc = CometContext.getInstance();
- cc.registChannel(CHANNEL);//注册应用的channel
- Thread helloAppModule = new Thread(new HelloAppModule(), "Sender App Module");
- helloAppModule.setDaemon(true);
- helloAppModule.start();
- }
- class HelloAppModule implements Runnable {
- public void run() {
- while (true) {
- try {
- Thread.sleep(1000);
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- CometEngine engine = CometContext.getInstance().getEngine();
- engine.sendToAll(CHANNEL, Runtime.getRuntime().freeMemory()/1024);
- }
- }
- }
- public void contextDestroyed(ServletContextEvent arg0) {
- }
- }
配置
web.xml
[html] view plaincopy
- <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>
- <listener>
- <description>HelloWorld</description>
- <listener-class>org.comet4j.demo.helloworld.HelloWorld</listener-class>
- </listener>
客户端使用简介
客户端是一个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,那么可以这样写:
[javascript] view plaincopy
- JS.Engine.start('/conn');
上段代码我们让浏览器与服务器进行连接,当连接成功以后JS.Engine类会发出"start"事件,如何进行事件的处理我们稍后介绍。
JS.Engine.stop方法
上面代码我们让连接断开,并传入了一个“主动断开”这样一个断开的原因。如果您并不需要对断开的原因进行说明,也可以不传递参数:
JS.Engine类的事件处理
上面我们介绍了如何使用start和stop方法来建立和断开连接,当成功建立连接已后JS.Engine会发出"start"事件,当断开后会发出“stop”事件,当收到某个通道推送过来的信息时也会发出与通道标识同名的事件。您可以事先在中使用JS.Engine.on方法来注册事件处理函数。例如:
[javascript] view plaincopy
- 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);
- });
也可以将上段代码写成,下面代码与上段代码完全等效:
[javascript] view plaincopy
- JS.Engine.on({
- start : function(cId, channelList, engine){
- alert('连接已建立,连接ID为:' + cId);
- },
- stop : function(cause, cId, url, engine){
- alert('连接已断开,连接ID为:' + cId + ',断开原因:' + cause + ',断开的连接地址:'+ url);
- }
- });
接下来,介绍一下如何对服务器推送过来的消息进行处理。在介绍之前,我们假设后台已经注册了一个"hello"的应用通道标识,并且只向客户端推送简单的字符串信息。先看如下代码:
[javascript] view plaincopy
- JS.Engine.on('hello',function(text){
- alert(text);
- });
这样当服务器端使用"hello"通道标识推送过来的消息就可以由上段代码进行处理,将推送过来的信息弹出。
特别注意:以上代码在事件处理函数中使用了alert仅为说明函数功能,实际使用中,在事件处理函数中切勿使用alert、prompt、confirm等可以中断脚本运行的函数,因为Engine需要实时的保持工作状态。
服务器端使用简介
服务端由一个Jar包组成,其中最重的是CometContext和CometEngine两个类。
Comet Context 类
CometContext是一个单态类,通过其getInstance方法来获得实例,它主要负责框架的一些初始化工作保存着一些参数的配置值,除此之外它还有一个更重要的职责——负责注册应用通道标识。如果您想使用框架来实现自己的应用,那么您必需要为自己的应用分配一个唯一的通道标识,并将此通道标识在WEB容器启动时使用CometContext的registChannel方法进行注册,这样,客户端才可以正确接受此应用所推送的消息。注册一个通道标识非常简单
[java] view plaincopy
- CometContext.getInstance().registChannel("hello");
这样便注册了一个标识为“hello”的应用通道,而客户也可以通过JS.Engine.on('hello',function(msg){...})的形式来接收并处理来自此通道的消息。
Comet Engine 类
另一个重要的类是CometEngine,它除了负责对连接的处理之外,对于开发人员而言,更加常用的可能是它所提供的sendTo或sendToAll方法来向客户端发送消息:
[java] view plaincopy
- 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等事件。通过对这些事件的处理来实现具体的功能:
[java] view plaincopy
- 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配置参数表
[html] view plaincopy
- <!--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>
利用Comet4J 及时推送消息相关推荐
- 利用server酱推送消息和定时库:APScheduler
转载自公众号:python_shequ 最近工作比较繁杂,经常忘事,有时候记了备忘录结果却忘记看备忘录,但是微信是每天都会看的,于是就想到写一个基于微信的提醒系统.总体思路是将待办事项记录到在线记事本 ...
- c#设计模式(3)—— 利用观察者模式模拟推送消息
1.观察者模式概念 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己的行为. 观察者模式实现了表 ...
- Web后台向前台推送消息(comet4j的使用)
一.简介: Comet4J(Comet for Java)是一个纯粹基于AJAX(XMLHTTPRequest)的服务器推送框架,消息以JSON方式传递,具备长轮询.长连接.自动选择三种工作模式.它是 ...
- 微信公众号为指定openid用户推送消息
微信公众号为指定openid用户推送消息 微信提供的开放接口中,有两个给指定openid的用户发送信息的接口,适用场景应该是向 预约用户或者中奖用户发送消息. 第一个接口:客服发送消息 请求方式: P ...
- Android中集成Jpush实现推送消息通知与根据别名指定推送附示例代码下载
场景 经常会有后台服务向Android推送消息通知的情况. 实现 首先在Android Studio中新建一个Android应用 在Project根目录的build.gradle中配置了jcenter ...
- php socket主动推送消息,PHP使用WebSocket主动推送【微信小程序接收】
WebSocket.jpeg Websocket是一种服务端和客户端可以持久连接的通信协议,我们可以利用WebSocket的特性实现服务器主动向客户端推送消息的功能. 这里我们用TP5.1框架结合Wo ...
- DWR实现服务器端向客户端推送消息
2019独角兽企业重金招聘Python工程师标准>>> 1.简介 DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框 ...
- Android Cloud to Device Messaging 服务介绍 – 如何使用云计算推送消息到手机(转载)...
基 于 Android 的手机是面向移动互联网的手机,保持24小时在线才能充分发挥它的全部能量.而 Google 也在不断提供各式各样的网络服务来吸引用户,有的服务是直接面向终端用户,而有的服务是面向 ...
- 服务器主动推送消息数据给客户端
1 引言 这个问题第一次是我在实现一个导师的方案的时候所发现的,一开始我需要实现服务器与客户端的密钥协商和数据传递,服务器需要主动分发(推送)密钥给客户端,因为以前没有做过相关编码,后来只能想到用反向 ...
最新文章
- password is not set 问题解决
- python no module name_python导包显示No module named XXX问题
- C++trie树的多重搜索算法的实现(附完整源码)
- 使用WebApiClient请求和管理Restful Api
- BZOJ4520 CQOI2016K远点对(KD-Tree+堆)
- mac 切换鼠标滚轮方向
- 【python入门到实践1】简介和环境搭建
- 消息队列(MQ)比较
- java实训自我总结_java实训个人总结
- 米思齐 Mixly 解决函数模块无法上下连接。
- Bean无法注入,‘sqlSessionFactory‘ threw exception,‘dataSource‘ threw exception大坑
- 【3D游戏基础】蒙皮骨骼动画与骨架
- git fetch总结
- 谷歌2022年共发放1200万美元赏金,单个最高60.5万美元
- Android:仿QQ 发表说说/上传照片 弹出框
- Kubernetes写yaml文件遇到的尴尬事情
- 手把手教你使用ModelArts的自动学习识别毒蘑菇分类
- java 截屏 锁屏黑色_Appium 解决锁屏截屏问题(java篇)
- 猫盘群晖DSM7.0三合一修复脚本
- 草根创业是不是真的不行了
热门文章
- 腾讯开放TAPD、持续集成平台等核心研发工具,加速AI落地
- 查看mysql库和表的大小(空间)
- 4.mysql数据库创建,表中创建模具模板脚本,mysql_SQL99标准连接查询(恩,外部连接,全外连接,交叉连接)...
- 解决sqlserver1433端口占用问题
- FTP匿名用户的配置
- 信赖域反射算法求解非线性大规模边界约束极小化问题
- Mathematica基础——Part——[[]]
- c++中extern,static,const关键字的作用
- linux下-exec和xargs的区别
- 数字图像处理:基于MATLAB的车牌识别项目