comet4j运用

j2ee 专栏收录该内容
3 篇文章 0 订阅

comet4j

1.可做聊天室,可做推送

2.上下线、消息处理

3.客户端异常下线捕捉


在做聊天室的过程中,遇到以下几个问题:

1.退出聊天网页时,想提示其他人下线,所以关键是捕捉下线信息,可是下线情况有很多种,点击关闭网页、异常断电等,开始本来想的是客户端与服务器用ajax进行心跳检测,可是后来一想,comet本来就是长连接的机制,后来通过查资料和测试,发现addDropListener可以捕捉下线情况,只需要在里面进行相关处理即可

2.Exception in thread “CometConnectorCleaner Thread” NullPointExcaption,这个原因一般发生在我们relaoding的情况下,而restart时不会发生,也就是说我们在部署服务器时,不能relaod。(猜测原因可能是comet4j内部线程在relaod时还在运行,而我们调用的前端代码却销毁后又开启,才会导致这样)

initWebSocket:function(){
    		JS.Engine.start('/kjzg/conn');
    		var onEvent ={
    			start:function(cId,channelList,engine){
    				
    			},
			webchat:function(message) {
			},
    			stop:function(){
    				// todo
    			}
    		};
    		JS.Engine.on(onEvent);
    	},

package com.webchat;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.comet4j.core.CometContext;
import org.comet4j.core.CometEngine;
import org.comet4j.core.event.ConnectEvent;
import org.comet4j.core.event.DropEvent;
import org.comet4j.core.event.RevivalEvent;
import org.comet4j.core.listener.ConnectListener;
import org.comet4j.core.listener.DropListener;
import org.comet4j.core.listener.RevivalListener;

import com.common.Constants;

import net.sf.json.JSONObject;

/**
 * 聊天服务器类
 * @author yinboqi
 *
 */
public class ChatServer implements ServletContextListener {
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 日期格式化
    private static final String CHANNEL = "webchat";
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		System.out.println("初始化聊天服务程序comet4j");
        CometContext cc = CometContext.getInstance();
        cc.registChannel(CHANNEL);//注册应用的channel
        CometEngine engine = cc.getEngine();
        //用户上线监听器内部类
        engine.addConnectListener(new ConnectListener() {
			
			@Override
			public boolean handleEvent(ConnectEvent arg0) {
				// TODO Auto-generated method stub
				System.out.println(arg0.getConn().getId()+" join-chat-----------");
				return true;
			}
		});
        //用户Drop监听器内部类
        engine.addDropListener(new DropListener() {
			
			@Override
			public boolean handleEvent(DropEvent arg0) {
				// TODO Auto-generated method stub
				Iterator<String> it=Constants.chatRoomMap.keySet().iterator();
				//遍历房间
				Boolean flag=true;
				while(it.hasNext() && flag){
					String key=it.next();
					ArrayList<String> Conns= Constants.chatRoomMap.get(key).getConns();
					//遍历房间成员
						for(int i=0;i<Conns.size();i++){
							//找到该成员
							if(Conns.get(i).equals(arg0.getConn().getId())){
								Conns.remove(i);
								Constants.chatRoomMap.get(key).setConns(Conns);			
								//发送在线人数更新命令
								JSONObject mjson=new JSONObject();
								mjson.put("ordernum", Constants.WEBCAHT_ONLINEUPDATE);//在线人数更新命令
								mjson.put("liveId", key);
								mjson.put("onlines", Constants.chatRoomMap.get(key).getConns().size());
								engine.sendToAll(CHANNEL, mjson);
									
								flag=false;//退出whille循环
								break;//退出for循环
							}
						}
					
				}
				System.out.println(arg0.getConn().getId()+" drop-chat-----------");
				return true;
			}
		});
      //用户Revival监听器内部类
        engine.addRevivalListener(new RevivalListener() {
			
			@Override
			public boolean handleEvent(RevivalEvent arg0) {
				// TODO Auto-generated method stub
				//复活线程
				return true;
			}
		}); 
    }



	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		
	}

}

package com.webchat;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.comet4j.core.CometConnection;
import org.comet4j.core.CometContext;
import org.comet4j.core.CometEngine;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.common.Constants;
import com.customer.entity.ChatRoom;

import net.sf.json.JSONObject;

/**
 *主体控制类
 */
@Controller
@RequestMapping("/ctrl/chat" )
public class ChatController{
	SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static Logger Log = Logger.getLogger(ChatController.class);
	private static final String CHANNEL = "webchat";//命令通道
         
	@SuppressWarnings("rawtypes")
	@RequestMapping("/sendMessageToAll")
	@ResponseBody
	//向所有人发送消息   
	public Map sendMessageToAll(HttpServletRequest request,HttpServletResponse response){
		
		System.out.println("sendMessageToAll");
		
		Map map = new HashMap();
		JSONObject mjson=new JSONObject();
		//当前直播间liveid
		String liveId=request.getParameter("liveId");
		//当前连接id
		String cid=request.getParameter("cid");
	    //消息正文
		String content=request.getParameter("content");
		//用户昵称
		String nickname=request.getParameter("nickname");
		String sendDate=sf.format(new Date());
		mjson.put("content", content);
		mjson.put("date", sendDate);
		mjson.put("nickname", nickname);
		//获得comet4j实例
        CometContext cc = CometContext.getInstance();
        CometEngine engine = cc.getEngine();
        //获取当前所有连接用户
        List<CometConnection> conns=engine.getConnections();
        for(CometConnection conn : conns){
        	//给自己推送
        	if(conn.getId().equals(cid)){
        		mjson.put("isSelf", 1);
        		engine.sendTo(liveId, conn, mjson.toString());
        		mjson.remove("isSelf");
        	//当前直播间其他人推送
        	}else{
        		engine.sendTo(liveId, conn, mjson.toString());
        	}
        }

		return map;
	}
	
	@SuppressWarnings("rawtypes")
	@RequestMapping("/sendOrderToAll")
	@ResponseBody
	//向所有人推送命令  
	public Map sendOrderToAll(HttpServletRequest request,HttpServletResponse response){
		System.out.println("sendOrderToAll");
		Map map = new HashMap();
		JSONObject mjson=new JSONObject();
	    //命令编码
		String ordernum=request.getParameter("ordernum");
		//直播间id
		String liveId=request.getParameter("liveId");
		mjson.put("ordernum", ordernum);
		mjson.put("liveId", liveId);
		//获得comet4j实例
        CometContext cc = CometContext.getInstance();
        CometEngine engine = cc.getEngine();
        //向所有用户推送命令
        engine.sendToAll(CHANNEL, mjson);
		return map;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("/registChatRoom")
	@ResponseBody
	//注册当前直播间聊天室
	public Map registChatRoom(HttpServletRequest request,HttpServletResponse response){
		System.out.println("registChatRoom");
		Map map = new HashMap();
		//当前直播间liveid
		String liveId=request.getParameter("liveId");
		//获得comet4j实例
        CometContext cc = CometContext.getInstance();
        CometEngine engine = cc.getEngine();
        //封装命令体
		JSONObject mjson=new JSONObject();
		mjson.put("ordernum", Constants.WEBCAHT_OPEN);//开启聊天室命令
		mjson.put("liveId", liveId);
        try {
        //判断此聊天室是否已经注册
        for(String channel : cc.getAppModules()){
        	if(channel.equals(liveId)){
        		//发送开启聊天室命令
        		engine.sendToAll(CHANNEL, mjson);
				map.put("Ret", 1);
				map.put("Msg", "聊天室已注册,开启成功!");
				map.put("Data", true);
				//聊天状态开启
				Constants.chatRoomMap.get(liveId).setStatus(1);
        		return map;
        	}
        }

            //直播间id号注册聊天室channel
            cc.registChannel(liveId);
            //发送开启聊天室命令
    		engine.sendToAll(CHANNEL, mjson);
			
		} catch (Exception e) {
			// TODO: handle exception
			map.put("Ret", 0);
			map.put("Msg", e.getMessage());
			map.put("Data", false);
	        return map;
		}
        map.put("Ret", 1);
		map.put("Msg", "聊天室注册成功,开启成功!");
		map.put("Data", true);
		//聊天状态开启
		Constants.chatRoomMap.get(liveId).setStatus(1);
        return map;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("/closeChatRoom")
	@ResponseBody
	//关闭当前直播间聊天室
	public Map closeChatRoom(HttpServletRequest request,HttpServletResponse response){
		System.out.println("closeChatRoom");
		Map map = new HashMap();
		//当前直播间liveid
		String liveId=request.getParameter("liveId");
		//获得comet4j实例
        CometContext cc = CometContext.getInstance();
        CometEngine engine = cc.getEngine();
        //封装命令体
		JSONObject mjson=new JSONObject();
		mjson.put("ordernum", Constants.WEBCAHT_CLOSE);//关闭聊天室命令
		mjson.put("liveId", liveId);
        try {

            //发送关闭聊天室命令
    		engine.sendToAll(CHANNEL, mjson);
			
		} catch (Exception e) {
			// TODO: handle exception
			map.put("Ret", 0);
			map.put("Msg", e.getMessage());
			map.put("Data", false);
	        return map;
		}
        map.put("Ret", 1);
		map.put("Msg", "聊天室已关闭!");
		map.put("Data", true);
		//聊天状态关闭
		Constants.chatRoomMap.get(liveId).setStatus(0);
        return map;
	}
	
	
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping("/initChatRoom")
	@ResponseBody
	//初始化直播间聊天室
	public Map initChatRoom(HttpServletRequest request,HttpServletResponse response){
		System.out.println("initChatRoom");
		Map map = new HashMap();
		//当前直播间liveid
		String liveId=request.getParameter("liveId");
		//当前连接id
		String cid=request.getParameter("cid");
		//获得comet4j实例
        CometContext cc = CometContext.getInstance();
        CometEngine engine = cc.getEngine();
		try {
		
		//判断聊天室是否存在
		if(Constants.chatRoomMap.containsKey(liveId)){

			//判断聊天功能是否在进来之前已经开启
			if(Constants.chatRoomMap.get(liveId).getStatus() ==1){
		        //封装命令体
				JSONObject mjson=new JSONObject();
				mjson.put("ordernum", Constants.WEBCAHT_OPEN);//开启聊天室命令
				mjson.put("liveId", liveId);
				//发送开启聊天功能命令
				engine.sendTo(CHANNEL, engine.getConnection(cid), mjson);
			}
		}else{
			//第一个人进入 增加聊天室记录
			ChatRoom chatRoom=new ChatRoom();
			chatRoom.setConns(new ArrayList());
			chatRoom.setStatus(0);
			Constants.chatRoomMap.put(liveId, chatRoom);
		}
		} catch (Exception e) {
			// TODO: handle exception
			map.put("Ret", 0);
			map.put("Msg", e.getMessage());
			map.put("Data", false);
	        return map;
		}
		//人数+1
		ArrayList<String> Conns=Constants.chatRoomMap.get(liveId).getConns();
		Conns.add(cid);
		Constants.chatRoomMap.get(liveId).setConns(Conns);
		//发送在线人数更新命令
		JSONObject mpjson=new JSONObject();
		mpjson.put("ordernum", Constants.WEBCAHT_ONLINEUPDATE);//在线人数更新命令
		mpjson.put("liveId", liveId);
		mpjson.put("onlines", Constants.chatRoomMap.get(liveId).getConns().size());
		engine.sendToAll(CHANNEL, mpjson);
		
        map.put("Ret", 1);
		map.put("Msg", "聊天室初始化成功!");
		map.put("Data", true);
        return map;

	}
	
}


  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值