1.准备工作:
1、下载comet4j.js
2、下载comet4j-tomcat7.jar 这个现在只支持tomcat6和7两个版本 一定要对应上了,我这边测试的 在tomcat8下面是用comet4j-tomcat7.jar这个jar文件也是可以推送的
2.maven配置
因为comet4j-tomcat6.jar这个jar文件在maven远程仓库中不存在,所以需要将jar包放到lib下面,但是maven打包的时候会找不到这个jar文件 所以在pom.xml中加入下面代码即可
<dependency>
<groupId>comet4j-tomcat7</groupId>
<artifactId>test</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/webapp/WEB-INF/lib/comet4j-tomcat7.jar</systemPath>
</dependency>
3.修改tomcat配置文件conf/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" URIEncoding="UTF-8"/>
4.修改web.xml配置
<listener>
<description>Comet4J容器侦听</description>
<listener-class>org.comet4j.core.CometAppListener</listener-class>
</listener>
<listener>
<description>监听我们自己的推送类</description>
<listener-class>com.util.CometUtil</listener-class>
</listener>
<servlet>
<description>客户端访问入口</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>
5.java后端推送工具类
CometUtil.java
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());
}
}
Constant.java
public class Constant {
public static long EXPIRE_AFTER_ONE_HOUR = 30; //cache过期时间
public static String CHANNEL_MSGCOUNT= "msgCount";
public static String CHANNEL_MSG_DATA= "msgData";
}
Comet.java
import java.util.List;
import java.util.Map;
public class Comet {
private String userId;
private String msgCount;
private List<Map> msgData;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMsgCount() {
return msgCount;
}
public void setMsgCount(String msgCount) {
this.msgCount = msgCount;
}
public List<Map> getMsgData() {
return msgData;
}
public void setMsgData(List<Map> msgData) {
this.msgData = msgData;
}
}
Cache.java
public class Cache {
private String key;
private Object value;
private long timeOut;
private boolean expired;
public Cache() {
super();
}
public Cache(String key, String value, long timeOut, boolean expired) {
this.key = key;
this.value = value;
this.timeOut = timeOut;
this.expired = expired;
}
public String getKey() {
return key;
}
public long getTimeOut() {
return timeOut;
}
public Object getValue() {
return value;
}
public void setKey(String string) {
key = string;
}
public void setTimeOut(long l) {
timeOut = l;
}
public void setValue(Object object) {
value = object;
}
public boolean isExpired() {
return expired;
}
public void setExpired(boolean b) {
expired = b;
}
}
CacheManager.java
public class CacheManager {
private static HashMap cacheMap = new HashMap();
/**
* This class is singleton so private constructor is used.
*/
private CacheManager() {
super();
}
/**
* returns cache item from hashmap
* @param key
* @return Cache
*/
private synchronized static Cache getCache(String key) {
return (Cache)cacheMap.get(key);
}
/**
* Looks at the hashmap if a cache item exists or not
* @param key
* @return Cache
*/
private synchronized static boolean hasCache(String key) {
return cacheMap.containsKey(key);
}
/**
* Invalidates all cache
*/
public synchronized static void invalidateAll() {
cacheMap.clear();
}
/**
* Invalidates a single cache item
* @param key
*/
public synchronized static void invalidate(String key) {
cacheMap.remove(key);
}
/**
* Adds new item to cache hashmap
* @param key
* @return Cache
*/
private synchronized static void putCache(String key, Cache object) {
cacheMap.put(key, object);
}
/**
* Reads a cache item's content
* @param key
* @return
*/
public static Cache getContent(String key) {
if (hasCache(key)) {
Cache cache = getCache(key);
if (cacheExpired(cache)) {
cache.setExpired(true);
}
return cache;
} else {
return null;
}
}
/**
*
* @param key
* @param content
* @param ttl
*/
public static void putContent(String key, Object content, long ttl) {
Cache cache = new Cache();
cache.setKey(key);
cache.setValue(content);
cache.setTimeOut(ttl + new Date().getTime());
cache.setExpired(false);
putCache(key, cache);
}
public static void putContent(String key, Object content) {
Cache cache = new Cache();
cache.setKey(key);
cache.setValue(content);
cache.setExpired(false);
putCache(key, cache);
}
/** @modelguid {172828D6-3AB2-46C4-96E2-E72B34264031} */
private static boolean cacheExpired(Cache cache){
if (cache == null) {
return false;
}
long milisNow = new Date().getTime();
long milisExpire = cache.getTimeOut();
if (milisExpire < 0) { // Cache never expires
return false;
} else if (milisNow >= milisExpire) {
return true;
} else {
return false;
}
}
}
6、前端jsp代码
在前段要显示推送的页面引入js
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<script type="text/javascript" src="${ctx }/js/comet4j.js"></script>
<script type="text/javascript">
var count = 0;
window.onload = function(){
// 建立连接,conn 即web.xml中 CometServlet的<url-pattern>
JS.Engine.start('${ctx}/conn');
<%
//保存用户id到session中
session.setAttribute("currentUserId",user.getId().toString());
%>
// 监听后台某个频道
JS.Engine.on(
{
// 对应服务端 “频道1” 的值 msgCount
msgCount : function(msgCount){
$("#msgCount").html(msgCount);
},
// 对应服务端 “频道2” 的值 msgData
msgData : function(msgData){
$("#msgData").html(msgData);
},
}
);
}
</script>
<body>
消息数量:<span id="msgCount"></span>
消息数据:<span id="msgData"></span>
</body>
经过以上的工作,我们就可以实现推送了 ,项目启动后,在任何类中调用下面的代码就可以推送给前端了,例如:
//所有客户端推送:
Comet comet = new Comet();
comet.setMsgCount(String.valueOf(msgCount));
comet.setMsgData(resultList);
new CometUtil()..pushToAll(comet);
//精准推送给某个客户端
Comet comet = new Comet();
comet.setUserId("1");//前端到session中的用户id
comet.setMsgCount(String.valueOf(msgCount));
comet.setMsgData(resultList);
new CometUtil()..pushTo(comet);
那么怎么实现实时推送呢 ,我用的是spring定时任务 定时扫描需要推送的内容 然后在调用推送工具类
spring定时器配置
1、pom.xml中引入依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
2、spring.xml文件加入下面代码
<!-- 消息推送定时任务 -->
<!-- 定时器配置 -->
<bean id="pushMessageTask" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class="com.util.timeTask.PushMessageTimer"/>
</property><!-- 指定任务类 -->
<property name="targetMethod" value="doit"></property><!-- 指定任务方法 -->
</bean>
<!-- 定义时间间隔触发器 -->
<bean id="pushMessageTigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="pushMessageTask"></property>
<property name="cronExpression">
<value>*/10 * * * * ?</value><!-- 10秒执行一次 -->
</property>
</bean>
<!-- 启动定时器 -->
<bean id="startQuertz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="pushMessageTigger"/>
</list>
</property>
3、PushMessageTimer.java
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.MessageMapper;
import com.Comet;
import com.util.CometUtil;
public class PushMessageTimer {
@Autowired
MessageMapper messageMapper;
private static CometUtil cometUtil = null;
public void doit(){
if(cometUtil == null){
cometUtil = new CometUtil();
}
List<Map> resultList = null;
int msgCount = 0;
try {
// String userId = (String) request.getSession().getAttribute("currentUserId");//精准推送需要获取前端保存到session的用户id
resultList = messageMapper.getUnReadMessageList(null);
msgCount = messageMapper.getUnReadMessageCount(null);
//推送消息
Comet comet = new Comet();
// comet.setUserId(userId);
comet.setMsgCount(String.valueOf(msgCount));
comet.setMsgData(resultList);
cometUtil.pushToAll(comet);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
相关推荐
Java 使用 Comet4j 主动向客户端推送信息是一个常见的实时通信技术,主要应用于构建WebSocket或长轮询等实时交互的应用场景。Comet4j 是一个基于 HTTP 长连接的服务器端框架,它允许服务器端主动向客户端推送数据,...
基于服务器推送框架 Comet4J ,后台模拟实时生成 gps 坐标信息然后再推送到前端页面显示。...这是客户端主动向服务器发起请求的方式,而采用 comet4j框架来实现正好相反,是服务器主动向客户端来推送消息。
在Web应用中,通常的HTTP请求是客户端发起的,而Comet打破了这种模式,使得服务器可以在适当的时候主动向客户端推送信息,极大地提升了实时性。 这个"comet demo"是一个展示如何在Java环境下利用Tomcat服务器实现...
总的来说,Comet4j是一种高效、便捷的Java实现的服务器端向客户端推送技术,它简化了实时通信的开发过程,特别适合那些需要频繁数据更新的应用场景。通过使用Comet4j,开发者可以专注于业务逻辑的实现,而无需过多地...
在JavaWeb开发中,实时通信是一项重要的功能,它允许服务器主动向客户端推送数据,而不仅仅是响应客户端的请求。本示例介绍的是如何使用Comet4j这个第三方库来实现后台到前台的消息推送功能。Comet4j是一个专门用于...
Comet4j是一个Java库,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天室、股票报价、在线游戏等实时交互功能...
Comet4j是一个Java框架,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天、实时通知、股票更新等功能,它克服...
服务器端的代码可能会创建一个Comet服务,监听特定的URL,并在有新数据时通过这个连接向客户端推送。客户端则会建立一个持久的HTTP连接,等待服务器的推送。 在Java中实现Comet4j推送,你需要做以下几步: 1. 引入...
总结来说,"java推送例子"是关于使用DWR库在Java环境中实现Web应用实时推送的一个示例。通过研究和理解这个项目,开发者能够掌握DWR的工作原理,以及如何在实际项目中运用推送技术,提升Web应用的用户体验。
3. 相关例子: 压缩包中可能包含了若干示例代码,这些代码展示了如何使用Comet4J进行服务器推送。通过这些示例,开发者可以快速理解和学习如何在实际项目中应用Comet4J,包括如何配置服务器端的Comet4J服务,如何在...
总的来说,这个"DWR Java推送例子 免积分"提供了一个学习和实践DWR实时推送功能的机会,特别适合那些希望在Web应用中实现即时通信功能的开发者。通过理解并实践这个例子,你可以更好地掌握DWR的使用,以及如何在不...
下面是一个使用Comet4J发送消息的实例代码示例,这个例子展示了如何在Java应用中实现服务器推送: ```java import org.comet4j.client.CometClient; import org.comet4j.client.CometEvent; public class Comet4...
Comet是一种Web应用程序架构,用于创建持久连接,允许服务器向客户端(通常是浏览器)实时推送数据。在传统的HTTP协议中,服务器只能在客户端发起请求时发送数据,而Comet通过长时间保持一个HTTP连接开放,使得...
Comet是Web开发中用于实现服务器向客户端推送数据的一种策略。它通常通过长时间保持一个HTTP连接来实现,使得服务器可以在准备好数据后立即推送给客户端,而不需要等待客户端的下一次请求。Comet技术包括两种主要...
Comet是一种Web编程模式,用于实现服务器向客户端的持久连接,从而实现数据的即时推送。Spring框架是Java领域广泛使用的轻量级应用框架,它可以与DWR结合,帮助开发者更方便地管理服务和组件。 在这个例子中,我们...
Comet框架是一个用于创建高效、实时Web应用的服务器端技术,它主要处理持久连接,使得服务器可以主动向客户端推送数据,而不仅仅局限于传统的HTTP请求-响应模式。在本"Comet框架例子项目"中,我们可以深入理解并学习...
这个过程被称为“反向Ajax”或“服务器推送”,它能够实现在不依赖用户操作的情况下,服务器主动向客户端发送数据。 DWR的核心组件包括几个部分: 1. **Engine**:这是DWR的核心,负责处理JavaScript到Java的转换和...
这个"**dwr简单推送例子**"是一个示例项目,旨在展示如何利用DWR实现服务端向客户端的实时数据推送功能,这是Web应用中实现即时更新、实时聊天或通知的关键技术。 DWR的核心功能是通过AJAX(Asynchronous ...
Comet技术是一种优化Web应用程序实时通信的技术,它允许服务器向客户端推送数据,而不仅仅是响应客户端的请求。在传统的HTTP协议中,服务器只能在客户端发起请求时返回数据,但Comet打破了这种模式,通过长时间保持...
Comet是Web实时通信的一种技术,通过长时间运行的HTTP连接(长轮询、HTTP流、WebSocket等)使服务器能够主动向客户端推送数据。这种模式克服了传统的HTTP请求-响应模型的限制,提高了实时性,适用于聊天应用、股票...