websocket实现多房间多人在线聊天室
文章图片
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 = newConcurrentHashMap>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
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 = "https://www.it610.com/article/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
Insert title here - 锐客网 span:HOVER{
color: red;
}
span{
cursor:pointer;
}
用户名:/*注:请先输入用户名,且保证用户名唯一,再点击下面的房间加入房间
room1
room2
room.jsp
聊天室 - 锐客网
<--退出房间欢迎来到:${roomid }
文章图片
${member.username }
${member.userid }
${sessionScope.uname }
web.xml
springMVC
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
org.springframework.web.context.ContextLoaderListener
contextConfigLocationclasspath:applicationContext.xml
org.springframework.web.util.IntrospectorCleanupListener
encoding
org.springframework.web.filter.CharacterEncodingFilter
【websocket实现多房间多人在线聊天室】encodingUTF-8
encoding
/*
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocationclasspath:springmvc.xml
springmvc*.do
文章图片
文章图片
源码下载地址:
链接:https://pan.baidu.com/s/1x1uHFTGKcMhtpwTV3Vd7Xg
提取码:c009
转载于:https://www.cnblogs.com/gaby-gl/articles/9802504.html
推荐阅读
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 爱就是希望你好好活着
- 昨夜小楼听风
- 知识
- 死结。
- 我从来不做坏事
- 烦恼和幸福
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息