websocket实现多房间多人在线聊天室

websocket实现多房间多人在线聊天室_第1张图片

package com.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@RequestMapping("/home")
@SessionAttributes("uname")
public class ViewController {
	
	@RequestMapping("/list")
	public String cc(ModelMap model){
		return "index";
	  }
	
	@RequestMapping("/room")
	public String h(ModelMap model,String uname,String roomid){
		model.put("uname",uname);
		model.put("roomid", roomid);
		return "room";
	}
}

  

package com.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;


import net.sf.json.JSONObject;


@ServerEndpoint("/websocket/{info}")
public class WebSocketService {

	private static SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//创建时间格式对象
	//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketService对象。
	//创建一个房间的集合,用来存放房间
	private static ConcurrentHashMap> roomList = new  ConcurrentHashMap>();
	//与某个客户端的连接会话,需要通过它来给客户端发送数据
	private Session session;
  //重新加入房间的标示;
  private int rejoin = 0;
    
   /*static {
    	roomList.put("room1", new ConcurrentHashMap());
    	roomList.put("room2", new ConcurrentHashMap());
    }*/

  /**
   * 用户接入
   * @param param  连接websocket服务器时穿的参数
   * @param session 会话
   */
	@OnOpen
	public void onOpen(@PathParam(value = "info") String param,Session session){
		System.err.println("登录时候穿的参数"+param.toString());
		this.session = session;
		String flag = param.split("[|]")[0]; 		//标识
		String member = param.split("[|]")[1];		//成员名
		if(roomList.get(member)==null){//判断房间列表中是否有此次的房间名称
			roomList.put(member, new ConcurrentHashMap());//如果没有将房间添加到房间列表中
		}
		//判断标志位是不是加入房间
		if(flag.equals("join")){
			String user = param.split("[|]")[2]; //截取用户名
			//调用加入房间的方法,传入房间名称和用户名称
			joinRoom(member,user);		
		}
	}
	
	/**
	 * 加入房间
	 * @param member 房间号
	 * @param user 用户名
	 */
	public void joinRoom(String member,String user){
		//从房间列表中获取房间
		ConcurrentHashMap r =  roomList.get(member);
		System.out.println(r.get(user));
		if(r.get(user) != null){		//该用户有没有在房间中
			this.rejoin = 1;//重新加入房间标志位1(一旦重新加入房间,以前的页面用户将看不到消息)
		}
		r.put(user, this);//将此用户加入房间中
	}
	
	/**
	 * 发送消息的方法
	 * @param message  需要发送的消息
	 * @throws IOException
	 */
	public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
	/**
	 * 接收到来自用户的消息
	 * @param message 接受的消息
	 * @param session 回话
	 * @throws IOException 
	 */
	@OnMessage
	public void onMessage(String message,Session session) throws IOException{
		
		//把用户发来的消息解析为JSON对象
		JSONObject obj = JSONObject.fromObject(message);
		System.out.println(obj.toString());
		//判断接受到的消息的标志位是什么(退出房间和发消息)
		if(obj.get("flag").toString().equals("exitroom")){		//退出房间操作
			String roomid = obj.get("roomid").toString();//取得房间编号
			System.out.println("roomid-"+roomid);
			//将用户从聊天室中移除
			int f2 = 1;
			roomList.get(roomid).remove(obj.get("nickname").toString());//将用户直接移除
			if(roomList.get(roomid).size() == 0){//判断房间该房间是否还有用户,如果没有,则将此房间也移除
				f2 = 2;
			}
			if(f2 == 1){		//证明该房间还有其它成员,则通知其它成员更新列表
				obj.put("flag","exitroom");
				String m = obj.get("nickname").toString()+" 退出了房间";
				obj.put("message", m);
				ConcurrentHashMap r =roomList.get(roomid);
				List uname = new ArrayList();
				for(String u:r.keySet()){
					uname.add(u);
				}
				obj.put("uname", uname.toArray());
				for(String i:r.keySet()){  //遍历该房间
					r.get(i).sendMessage(obj.toString());//调用方法 将消息推送
				}
			}
		}else if(obj.get("flag").toString().equals("chatroom")){		//聊天室的消息 加入房间/发送消息
			//向JSON对象中添加发送时间
			obj.put("date", df.format(new Date()));
			//获取客户端发送的数据中的内容---房间�? 用于区别该消息是来自于哪个房间
			String roomid = obj.get("target").toString();
			//获取客户端发送的数据中的内容---用户
			String username = obj.get("nickname").toString();
			//从房间列表中定位到该房间
			ConcurrentHashMap r =roomList.get(roomid);
			List uname = new ArrayList();
			for(String u:r.keySet()){
				uname.add(u);
			}
			obj.put("uname", uname.toArray());
			if(r.get(username).rejoin == 0){			//证明不是退出重连
				for(String i:r.keySet()){  //遍历该房间
					obj.put("isSelf", username.equals(i));//设置消息是否为自己的
					r.get(i).sendMessage(obj.toString());//调用方法 将消息推送
				}
			}else{
				obj.put("isSelf", true);
				r.get(username).sendMessage(obj.toString());
			}
			r.get(username).rejoin = 0;
		}
		
	}
	
	/**
	 * 用户断开
	 * @param session
	 */
	@OnClose
	public void onClose(Session session){
   System.out.println("退出聊天室");
	}
	
	/**
	 * 用户连接异常
	 * @param t
	 */
	@OnError
	public void onError(Throwable t){
		
	}
}

  

applicationContext.xml




  springmvc.xml



	
	
	
	
	
	
	
	
	
	
		
		
		
		
	

	

  index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>





Insert title here




	用户名:   /*注:请先输入用户名,且保证用户名唯一,再点击下面的房间加入房间
	

room1

room2

  

room.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>



<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>



聊天室




	
<--退出房间
欢迎来到:

${roomid }

${member.username } ${member.userid }

  web.xml



  springMVC
  
    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp
  
  
  
  
  	 org.springframework.web.context.ContextLoaderListener
  
  
  	contextConfigLocation
  	classpath:applicationContext.xml
  
  
  
  	org.springframework.web.util.IntrospectorCleanupListener
  
  
  
  
  		encoding
  		org.springframework.web.filter.CharacterEncodingFilter	
  		
  			encoding
  			UTF-8
  		
  
  
  		encoding
  		/*
  
  
  
  
  		springmvc
  		org.springframework.web.servlet.DispatcherServlet
  		
  			contextConfigLocation
  			classpath:springmvc.xml
  		
  
  
  		springmvc
  		
  		*.do
  
  
  

  websocket实现多房间多人在线聊天室_第2张图片

websocket实现多房间多人在线聊天室_第3张图片

 源码下载地址:

链接:https://pan.baidu.com/s/1x1uHFTGKcMhtpwTV3Vd7Xg
提取码:c009

转载于:https://www.cnblogs.com/gaby-gl/articles/9802504.html

你可能感兴趣的:(websocket实现多房间多人在线聊天室)