WebSocket通信聊天(Java)

基于netty-socketio-1.7.11.jar实现即时通信

实际效果展示
WebSocket通信聊天(Java)_第1张图片核心代码块
SocketServiceLoader.java

package com.linksaint.web.socket.service;

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

public class SocketServiceLoader implements ServletContextListener{
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
	     //启动Socketio服务
        Socketio socketio = new Socketio();
        socketio.startServer();
	} 
	
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		 //关闭Socketio服务
        Socketio socketio = new Socketio();
        socketio.stopSocketio();
	}

	
}

Socketio.java

package com.linksaint.web.socket.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.ContextLoader;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.linksaint.system.po.SysUser;
import com.linksaint.system.service.SysMaxIdService;
import com.linksaint.system.service.SysUserService;
import com.linksaint.util.DateUtils;
import com.linksaint.web.socket.listener.CharteventListener;
import com.linksaint.web.socket.listener.ChatConnectListenner;
import com.linksaint.web.socket.po.ChatConnect;
import com.linksaint.web.socket.po.ChatInfo;
import com.linksaint.web.socket.po.ChatRoom;
import com.linksaint.web.socket.po.ClientInfo;
import com.linksaint.web.socket.po.Room_user_rel;
/*
 * netty-socketio工具类
 * 启动、添加客户端
 * 消息推送
 * 关闭服务
 */
public class Socketio {
	@Autowired
	private ClientInfoService clientInfoService;
	@Autowired
	private ChatInfoService chatInfoService;
	@Autowired
	private ChatRoomService chatRoomService;
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private Room_user_relService room_user_relService;
	@Autowired
 	private SysMaxIdService sysMaxIdService;
    static SocketIOServer socketIOServer;
    /*
     * 添加客户端
     */
    public void startSocketio() throws InterruptedException {
        //配置
        Configuration conf = new Configuration();
        //指定要主机ip地址,这个和页面请求ip地址一致
//        conf.setHostname("192.168.0.67");
        conf.setHostname("192.168.0.129");
        //指定端口号
        conf.setPort(9092);
        //设置最大的WebSocket帧内容长度限制
        conf.setMaxFramePayloadLength(1024*1024);
        //设置最大HTTP内容长度限制
        conf.setMaxHttpContentLength(1024 * 1024);
        socketIOServer = new SocketIOServer(conf);
        System.out.println("服务器已经建立,,等待客户端连接。。");
    
    clientInfoService=(ClientInfoService) ContextLoader.getCurrentWebApplicationContext().getBean("clientInfoService");
    chatInfoService=(ChatInfoService) ContextLoader.getCurrentWebApplicationContext().getBean("chatInfoService");
    sysUserService=(SysUserService) ContextLoader.getCurrentWebApplicationContext().getBean("sysUserService");
    room_user_relService=(Room_user_relService) ContextLoader.getCurrentWebApplicationContext().getBean("room_user_relService");
    sysMaxIdService=(SysMaxIdService) ContextLoader.getCurrentWebApplicationContext().getBean("sysMaxIdService");
    chatRoomService=(ChatRoomService) ContextLoader.getCurrentWebApplicationContext().getBean("chatRoomService");
    /**
     * 添加连接监听事件,监听是否与客户端连接到服务器
     */
    socketIOServer.addConnectListener(new ConnectListener() {
        @Override
        public void onConnect(SocketIOClient client) {
            // 判断是否有客户端连接
            if (client != null) {
                System.out.println("链接成功。。。");
            } else {
                System.err.println("暂无人员链接。。。");
            }
            System.err.println(client.getSessionId().toString());
        }
    });
    
    
    /**
     * 添加连接监听事件,监听是否与客户端连接到服务器
     */
    socketIOServer.addDisconnectListener(new DisconnectListener() {
        @Override
        public void onDisconnect(SocketIOClient client) {
            // 判断是否有客户端连接
            if (client != null) {
                System.out.println("断开连接。。。");
              //根据客户端sessionID获取用户与client缓存中的信息  
                ClientInfo cInfo = clientInfoService.getClientInfoBycId(client.getSessionId().toString());
	               if(null!=cInfo){
	            	   cInfo.setConnected((short) 0);
	            	   clientInfoService.updateClient(cInfo);
	               }
                
            } else {
                System.err.println("暂无人员断开连接。。。");
            }
            System.err.println(client.getSessionId().toString());
        }
    });
    
    // 握手请求
    socketIOServer.addEventListener("helloevent", ChatConnect.class, new ChatConnectListenner() {
        @Override
        public void onData(final SocketIOClient client, ChatConnect data, AckRequest ackRequest) {
            // 握手
        	String s=data.getType()==0?"移动端":"web端";
        	  System.out.println("握手接收到"+s+"客户端"+data.getUserId()+"握手请求");
        	  long userId = data.getUserId();
        	  int type = data.getType();
        	  long roomId=data.getRoomId();
        	  //更加roomid类型,判断是群聊,群聊聊天室不存在就自动向注入此用户
        	  ChatRoom room=chatRoomService.selectChatRoomIdInfo(roomId);
        	  if(null!=room&&room.getType()==1){//群聊
        		   List rels= room_user_relService.getRelInfosByRoomId(roomId,userId);
        			   if(null!=rels&&rels.size()>0){
        				  System.out.println("此用户已绑定到该群聊聊天室!");
        			   }else{
        				   Room_user_rel rel=new Room_user_rel();
           					rel.setRoomid(roomId);
           					rel.setUserid(userId);
           					rel.setTargetid(0L);
           				   room_user_relService.addChatRel(rel);
        			   }
        	  }
        	  
                	ClientInfo clientInfo=null;
                	if(userId>0&&type>-1){
                		clientInfo = clientInfoService.getClientInfoByUserId(userId,type) ;	
                	}
    	    		if (clientInfo != null)
    	    		{
    	    			clientInfo.setClientid(client.getSessionId().toString());
    	    			clientInfo.setConnected((short)1);
    	    			clientInfo.setMostsignbits(client.getSessionId().getMostSignificantBits());
    	    			clientInfo.setLeastsignbits(client.getSessionId().getLeastSignificantBits());
    	    			clientInfo.setLastconnecteddate(DateUtils.getNowDate());
    	    			clientInfo.setUserId(userId);
    	    			clientInfo.setType(type);
    	    			clientInfo.setRoomId(roomId);
    	    			clientInfoService.updateClient(clientInfo);
    	    		}else{
    	    			ClientInfo info = new ClientInfo();
    	    			info.setClientid(client.getSessionId().toString());
    	    			info.setConnected((short)1);
    	    			info.setMostsignbits(client.getSessionId().getMostSignificantBits());
    	    			info.setLeastsignbits(client.getSessionId().getLeastSignificantBits());
    	    			info.setLastconnecteddate(DateUtils.getNowDate());
    	    			info.setUserId(userId);
    	    			info.setType(type);
    	    			info.setRoomId(roomId);
    	    			clientInfoService.addClient(info);
    	    		}

        }
    });
    
    
    
    //私信
    socketIOServer.addEventListener("message", ChatInfo.class, new CharteventListener() {
        @Override
        public void onData(SocketIOClient client, ChatInfo data,
                AckRequest ackSender) throws Exception {
        	SysUser user=sysUserService.GetUserById(data.getSourceUserId());
            System.out.println("私聊房间号:"+data.getRoomid()+"--"+user.getUserName()+":" + data.getMessage());
            //向客户端发送消息
            long chatid = sysMaxIdService.selectSysMaxId("chatMessage");
            data.setMessageId(chatid);
            data.setMessage(data.getMessage());
            data.setState(0);//初始状态未发送
            data.setSenddate(DateUtils.getNowDate());
            //获得消息所在房间
            List rels= room_user_relService.getRelInfosByRoomId(data.getRoomid());
            ChatRoom room=new ChatRoom();
            room.setId(data.getRoomid());
            room.setDate(DateUtils.getNowDate());
            room.setType(2);
            chatRoomService.updateChatRoom(room);
            for (Room_user_rel rel : rels) {
				if(rel.getTargetid()>0){//单聊聊天记录
					data.setTargetUserId(rel.getTargetid());
					long id=chatInfoService.insertChatInfo(data);
				}else{//群聊聊天记录
					if(!rel.getUserid().equals(data.getSourceUserId())){
						data.setTargetUserId(rel.getUserid());
						long id=chatInfoService.insertChatInfo(data);
					}
				}
			}
            
            Collection clients = socketIOServer.getAllClients();
            //发送给聊天室在线人员(不包括自己)
            List cons=clientInfoService.getClientInfosByRoomId(data.getRoomid(),data.getSourceUserId());
            for (ClientInfo info : cons) {
            	System.out.println("数据库中:"+info.getClientid());
            	 for (SocketIOClient c : clients) {
                 	System.out.println("socket服务中:"+c.getSessionId().toString());
                 	if(c.getSessionId().toString().equals(info.getClientid())){
                      c.sendEvent("message",data);
                      //如果客户端在线,更新消息发送状态为已发送
                      //判断用户活跃聊天室是否为当前消息聊天室
                      if(info.getRoomId()==data.getRoomid()){
                    	  chatInfoService.updateSendStateByclient(data.getRoomid(), data.getSourceUserId(), info.getUserId());
                      }
                    }
 				}
			}
        }
    });
    
    
    //群聊
    socketIOServer.addEventListener("chat", ChatInfo.class, new CharteventListener() {
        @Override
        public void onData(SocketIOClient client, ChatInfo data,
                AckRequest ackSender) throws Exception {
        	SysUser user=sysUserService.GetUserById(data.getSourceUserId());
            System.out.println("群聊房间号:"+data.getRoomid()+"--"+user.getUserName()+":" + data.getMessage());
            //向客户端发送消息
            long chatid = sysMaxIdService.selectSysMaxId("chatMessage");
            data.setMessageId(chatid);
            data.setMessage(data.getMessage());
            data.setState(0);//初始状态未发送
            data.setSenddate(DateUtils.getNowDate());
            //获得消息所在房间
            List rels= room_user_relService.getRelInfosByRoomId(data.getRoomid());
            List list=new ArrayList();
           if(null!=rels&&rels.size()==1){
        	   data.setTargetUserId(0);
				long id=chatInfoService.insertChatInfo(data);
				data.setId(id);
           }else{
        	   for (Room_user_rel rel : rels) {
				//群聊聊天记录
					if(!rel.getUserid().equals(data.getSourceUserId())){
						data.setTargetUserId(rel.getUserid());
						long id=chatInfoService.insertChatInfo(data);
						list.add(id);
					
				}
			 }
           }
            //获取群聊信息最小id一条数据
           if(list.size()>0){
        	   data.setId(list.get(0));
           }
            
            Collection clients = socketIOServer.getAllClients();
            //发送给聊天室在线人员(包括自己)
            List cons=clientInfoService.getAllClientInfosByRoomId(data.getRoomid());
            for (ClientInfo info : cons) {
            	System.out.println("数据库中:"+info.getClientid());
            	 for (SocketIOClient c : clients) {
                 	System.out.println("socket服务中:"+c.getSessionId().toString());
                 	if(c.getSessionId().toString().equals(info.getClientid())){
                      c.sendEvent("chat",data);
                    }
 				}
			}
        }
    });
    
    
    
    //各客户端同步群聊标记重点
    socketIOServer.addEventListener("sign", ChatInfo.class, new CharteventListener() {
        @Override
        public void onData(SocketIOClient client, ChatInfo data,
                AckRequest ackSender) throws Exception {
        	SysUser user=sysUserService.GetUserById(data.getSourceUserId());
            System.out.println("群聊房间号:"+data.getRoomid()+"-被标记重点Id-"+data.getId()+";是否标记(0:取消标记,1:标记):" + data.getStatus());
            
            Collection clients = socketIOServer.getAllClients();
            //发送给聊天室在线人员该条记录的标记次数(包括自己)
            List cons=clientInfoService.getAllClientInfosByRoomId(data.getRoomid());
            for (ClientInfo info : cons) {
//                	System.out.println("数据库中:"+info.getClientid());
            	 for (SocketIOClient c : clients) {
//                     	System.out.println("socket服务中:"+c.getSessionId().toString());
                 	if(c.getSessionId().toString().equals(info.getClientid())){
                      c.sendEvent("sign",data);
                    }
 				}
			}
        }
    });
    
    
    
    
    socketIOServer.start();
    
    //设置超时时间
    Thread.sleep(Integer.MAX_VALUE);
    
    socketIOServer.stop();
}

/**
 *  给所有连接客户端推送消息
 * @param eventType 推送的事件类型
 * @param message  推送的内容
 */
public static void sendMessageToAllClient(String eventType,ChatInfo message){
	//返回默认名称空间中的所有客户端实例。
    Collection clients = socketIOServer.getAllClients();
    //getBroadcastOperations() 返回默认名称空间的所有实例组成的广播对象。
    //getRoomOperations() 返回所有命名空间中指定房间的广播对象,如果命名空间只有一个,该方法到可以大胆使用。
    //getClient(uid) 返回默认名称空间的指定客户端。
    //getNamespace() 返回指定名称的命名空间。
    for(SocketIOClient client: clients){
    	System.out.println(client.getSessionId().toString());
        client.sendEvent(eventType,message);
    }
}


/*
 * 启动服务
 */
public void startServer() {
    if (socketIOServer == null) {
        new Thread(new Runnable() {
            @Override
            public void run() {
               try {
                startSocketio();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
        }).start();
    }
}

/*
 * 停止服务
 */
public void stopSocketio() {
    if (socketIOServer != null) {
        socketIOServer.stop();
        socketIOServer = null;
    }
}
}

你可能感兴趣的:(Java)