|
|
@@ -1,12 +1,16 @@
|
|
|
package com.zhongzheng.modules.socket.service;
|
|
|
|
|
|
+import cn.hutool.core.lang.Validator;
|
|
|
import com.zhongzheng.common.exception.CustomException;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import javax.validation.Valid;
|
|
|
import javax.websocket.*;
|
|
|
import javax.websocket.server.PathParam;
|
|
|
import javax.websocket.server.ServerEndpoint;
|
|
|
import java.io.IOException;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
@@ -17,7 +21,11 @@ public class WebSocketServer {
|
|
|
private static AtomicInteger onlineNum = new AtomicInteger();
|
|
|
|
|
|
//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
|
|
|
- private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
|
|
|
+ // private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
|
|
|
+ private static ConcurrentHashMap<String, Map<String,Session>> sessionPools = new ConcurrentHashMap<>(); //v是userAccount,v是Session
|
|
|
+ private static ConcurrentHashMap<String, String> namePools = new ConcurrentHashMap<>(); //key是tag,v是userAccount
|
|
|
+ private static ConcurrentHashMap<String, String> actionPools = new ConcurrentHashMap<>(); //存放每个会话的操作,key是tag,v是action
|
|
|
+
|
|
|
|
|
|
//发送消息
|
|
|
public void sendMessage(Session session, String message) throws IOException {
|
|
|
@@ -29,8 +37,9 @@ public class WebSocketServer {
|
|
|
}
|
|
|
}
|
|
|
//给指定用户发送信息
|
|
|
- public void sendInfo(String userName, String message){
|
|
|
- Session session = sessionPools.get(userName);
|
|
|
+ public void sendInfo(String userAccount,String tag, String message){
|
|
|
+ Map<String,Session> sessionMap = sessionPools.get(userAccount);
|
|
|
+ Session session = sessionMap.get(tag);
|
|
|
if(session==null){
|
|
|
throw new CustomException("webSocket不在线",505);
|
|
|
}
|
|
|
@@ -43,33 +52,85 @@ public class WebSocketServer {
|
|
|
|
|
|
//建立连接成功调用
|
|
|
@OnOpen
|
|
|
- public void onOpen(Session session, @PathParam(value = "sid") String userName){
|
|
|
- if(!sessionPools.containsKey(userName)){
|
|
|
- addOnlineCount();
|
|
|
+ public void onOpen(Session session, @PathParam(value = "sid") String userAccount){
|
|
|
+ String tag = null;
|
|
|
+ if(Validator.isNotEmpty(userAccount)){
|
|
|
+ tag = session.getId(); //用户不同端标识码
|
|
|
+ if(!namePools.containsKey(tag)){
|
|
|
+ namePools.put(tag,userAccount);
|
|
|
+ }
|
|
|
+ if(sessionPools.containsKey(userAccount)){
|
|
|
+ Map<String,Session> sessionMap = sessionPools.get(userAccount);
|
|
|
+ //用户新的终端连接进来
|
|
|
+ if(!sessionMap.containsKey(tag)){
|
|
|
+ sessionMap.put(tag,session);
|
|
|
+ addOnlineCount();
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ //用户所有端都没连接
|
|
|
+ Map<String,Session> sessionMap = new HashMap<>();
|
|
|
+ sessionMap.put(tag,session);
|
|
|
+ sessionPools.put(userAccount, sessionMap);
|
|
|
+ addOnlineCount();
|
|
|
+ }
|
|
|
+ System.out.println(userAccount + "加入webSocket!当前人数为" + onlineNum);
|
|
|
+ try {
|
|
|
+ sendMessage(session, "欢迎" + userAccount + "加入连接!");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ delPeople(tag);
|
|
|
+ }
|
|
|
}
|
|
|
- sessionPools.put(userName, session);
|
|
|
- System.out.println(userName + "加入webSocket!当前人数为" + onlineNum);
|
|
|
- try {
|
|
|
- sendMessage(session, "欢迎" + userName + "加入连接!");
|
|
|
- } catch (IOException e) {
|
|
|
- e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String delPeople(String tag){
|
|
|
+ String userAccount = null;
|
|
|
+ if(namePools.containsKey(tag)){
|
|
|
+ userAccount = namePools.get(tag);
|
|
|
+ namePools.remove(tag);
|
|
|
+ actionPools.remove(tag);
|
|
|
}
|
|
|
+ if(Validator.isNotEmpty(userAccount)){
|
|
|
+ if(sessionPools.containsKey(userAccount)){
|
|
|
+ Map<String,Session> sessionMap = sessionPools.get(userAccount);
|
|
|
+ if(sessionMap.containsKey(tag)){
|
|
|
+ sessionMap.remove(tag);
|
|
|
+ }
|
|
|
+ if(sessionMap.size()==0){
|
|
|
+ sessionPools.remove(userAccount);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ }
|
|
|
+ subOnlineCount();
|
|
|
+ return userAccount;
|
|
|
}
|
|
|
|
|
|
//关闭连接时调用
|
|
|
@OnClose
|
|
|
- public void onClose(@PathParam(value = "sid") String userName){
|
|
|
- sessionPools.remove(userName);
|
|
|
- subOnlineCount();
|
|
|
- System.out.println(userName + "断开webSocket连接!当前人数为" + onlineNum);
|
|
|
+ public void onClose(Session session){
|
|
|
+ String tag = session.getId();
|
|
|
+
|
|
|
+ if (Validator.isNotEmpty(tag)) {
|
|
|
+ String userAccount = delPeople(tag);
|
|
|
+ System.out.println(userAccount + "断开webSocket连接!当前人数为" + onlineNum);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
//收到客户端信息
|
|
|
@OnMessage
|
|
|
- public void onMessage(String message) throws IOException{
|
|
|
- message = "客户端:" + message + ",已收到";
|
|
|
- System.out.println(message);
|
|
|
+ public void onMessage(String message, Session session) throws IOException{
|
|
|
+ String tag = session.getId();
|
|
|
+ if(Validator.isNotEmpty(message)){
|
|
|
+ if (message.equals("doQuestion")) { //题库全部限制多开
|
|
|
+ doQuestion(tag,"doQuestion");
|
|
|
+ }
|
|
|
+ if (message.equals("doCourse")) { //课程继续教育限制多开
|
|
|
+ doQuestion(tag,"doCourse");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // message = "客户端:" + message + ",已收到";
|
|
|
+ // System.out.println(message+System.currentTimeMillis()/1000+namePools.get(session.getId()));
|
|
|
/*for (Session session: sessionPools.values()) {
|
|
|
try {
|
|
|
sendMessage(session, message);
|
|
|
@@ -95,4 +156,37 @@ public class WebSocketServer {
|
|
|
onlineNum.decrementAndGet();
|
|
|
}
|
|
|
|
|
|
+ //存储用户行为和发送下线消息给其他端
|
|
|
+ private boolean doQuestion(String tag,String nowAction){
|
|
|
+ String userAccount = null;
|
|
|
+ if(namePools.containsKey(tag)){
|
|
|
+ userAccount = namePools.get(tag);
|
|
|
+ actionPools.put(tag,nowAction);
|
|
|
+ }
|
|
|
+ if(Validator.isNotEmpty(userAccount)){
|
|
|
+ if(sessionPools.containsKey(userAccount)){
|
|
|
+ Map<String,Session> sessionMap = sessionPools.get(userAccount); //获取用户得所有端会话
|
|
|
+ for(String key : sessionMap.keySet()){
|
|
|
+ if(actionPools.containsKey(key)){
|
|
|
+ String action = actionPools.get(key); //获取用户所在的行为
|
|
|
+ if(!key.equals(tag)){
|
|
|
+ if(action.equals(nowAction)){
|
|
|
+ // System.out.println(key+"踢下线");
|
|
|
+ Session other = sessionMap.get(key);
|
|
|
+ //通知其他端下线
|
|
|
+ try {
|
|
|
+ sendMessage(other, "offLine");
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ delPeople(tag);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
}
|