|
|
|
@ -1,11 +1,18 @@
|
|
|
|
|
package cc.yunxi.utils;
|
|
|
|
|
|
|
|
|
|
import cc.yunxi.domain.vo.socket.AppTypeEnum;
|
|
|
|
|
import cc.yunxi.domain.vo.socket.SocketMessage;
|
|
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
import org.springframework.web.socket.TextMessage;
|
|
|
|
|
import org.springframework.web.socket.WebSocketSession;
|
|
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.util.Iterator;
|
|
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
|
|
|
|
|
|
|
@Slf4j
|
|
|
|
|
@Component
|
|
|
|
@ -14,7 +21,12 @@ public class WsSessionManager {
|
|
|
|
|
* 保存连接 session 的地方
|
|
|
|
|
*/
|
|
|
|
|
private static ConcurrentHashMap<String, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>();
|
|
|
|
|
private static ConcurrentHashMap<String, WebSocketSession> USER_SESSION_POOL = new ConcurrentHashMap<>();
|
|
|
|
|
//散户端session
|
|
|
|
|
private static ConcurrentHashMap<String, WebSocketSession> CLIENT_SESSION = new ConcurrentHashMap<>();
|
|
|
|
|
//回收端session
|
|
|
|
|
private static ConcurrentHashMap<String, WebSocketSession> RECYCLER_SESSION = new ConcurrentHashMap<>();
|
|
|
|
|
//消息缓存
|
|
|
|
|
private static final ConcurrentLinkedQueue<SocketMessage> MESSAGE_CACHE = new ConcurrentLinkedQueue<>();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加 session
|
|
|
|
@ -26,16 +38,31 @@ public class WsSessionManager {
|
|
|
|
|
SESSION_POOL.put(key, session);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addUserSession(String key, WebSocketSession session) {
|
|
|
|
|
public void addClientSession(String userId, WebSocketSession session) {
|
|
|
|
|
//获取旧session
|
|
|
|
|
WebSocketSession oldSession = USER_SESSION_POOL.get(key);
|
|
|
|
|
WebSocketSession oldSession = CLIENT_SESSION.get(userId);
|
|
|
|
|
if (null == oldSession //没有
|
|
|
|
|
|| !oldSession.getId().equals(session.getId()) //id不同
|
|
|
|
|
|| !oldSession.isOpen()) { //旧session已关闭
|
|
|
|
|
USER_SESSION_POOL.put(key, session); //则将新的session添加到池中
|
|
|
|
|
CLIENT_SESSION.put(userId, session); //则将新的session添加到池中
|
|
|
|
|
//判断缓存中是否有未发送的消息
|
|
|
|
|
sendCacheMessage(userId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addRecyclerSession(String userId, WebSocketSession session) {
|
|
|
|
|
//获取旧session
|
|
|
|
|
WebSocketSession oldSession = RECYCLER_SESSION.get(userId);
|
|
|
|
|
if (null == oldSession //没有
|
|
|
|
|
|| !oldSession.getId().equals(session.getId()) //id不同
|
|
|
|
|
|| !oldSession.isOpen()) { //旧session已关闭
|
|
|
|
|
RECYCLER_SESSION.put(userId, session); //则将新的session添加到池中
|
|
|
|
|
//判断缓存中是否有未发送的消息
|
|
|
|
|
sendCacheMessage(userId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除 session,会返回删除的 session
|
|
|
|
|
*
|
|
|
|
@ -44,10 +71,54 @@ public class WsSessionManager {
|
|
|
|
|
*/
|
|
|
|
|
public WebSocketSession remove(String key) {
|
|
|
|
|
// 删除 session
|
|
|
|
|
USER_SESSION_POOL.remove(key);
|
|
|
|
|
CLIENT_SESSION.remove(key);
|
|
|
|
|
return SESSION_POOL.remove(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//处理未发送的消息
|
|
|
|
|
private void sendCacheMessage(String userId) {
|
|
|
|
|
// 遍历缓存队列
|
|
|
|
|
Iterator<SocketMessage> iterator = MESSAGE_CACHE.iterator();
|
|
|
|
|
if (iterator.hasNext()) {
|
|
|
|
|
SocketMessage message = iterator.next();
|
|
|
|
|
LocalDateTime sendTime = message.getSendTime();
|
|
|
|
|
int minute = message.getCacheMinute();
|
|
|
|
|
AppTypeEnum appType = message.getAppType();
|
|
|
|
|
WebSocketSession session = null;
|
|
|
|
|
switch (appType) {
|
|
|
|
|
case client:
|
|
|
|
|
session = CLIENT_SESSION.get(userId);
|
|
|
|
|
break;
|
|
|
|
|
case recycler:
|
|
|
|
|
session = RECYCLER_SESSION.get(userId);
|
|
|
|
|
default:
|
|
|
|
|
iterator.remove();//移除
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (userId.equals(message.getReceiveUserId())
|
|
|
|
|
&& session != null
|
|
|
|
|
&& session.isOpen()
|
|
|
|
|
&& sendTime.plusMinutes(minute).isAfter(LocalDateTime.now())) {
|
|
|
|
|
// 发送消息
|
|
|
|
|
try {
|
|
|
|
|
session.sendMessage(new TextMessage(JSONUtil.toJsonStr(message)));
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
iterator.remove();//移除
|
|
|
|
|
}
|
|
|
|
|
//过期的消息直接移除
|
|
|
|
|
if (sendTime.plusMinutes(minute).isBefore(LocalDateTime.now())) {
|
|
|
|
|
iterator.remove();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//添加未发送的消息
|
|
|
|
|
public void addCacheMessage(SocketMessage message) {
|
|
|
|
|
MESSAGE_CACHE.add(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除并同步关闭连接
|
|
|
|
@ -68,14 +139,25 @@ public class WsSessionManager {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获得 session
|
|
|
|
|
* 获得预约端 session
|
|
|
|
|
*
|
|
|
|
|
* @param key
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public WebSocketSession getClientSession(String key) {
|
|
|
|
|
// 获得 session
|
|
|
|
|
return CLIENT_SESSION.get(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获得回收员端 session
|
|
|
|
|
*
|
|
|
|
|
* @param key
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public WebSocketSession getUserSession(String key) {
|
|
|
|
|
public WebSocketSession getRecyclerSession(String key) {
|
|
|
|
|
// 获得 session
|
|
|
|
|
return USER_SESSION_POOL.get(key);
|
|
|
|
|
return RECYCLER_SESSION.get(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -86,7 +168,7 @@ public class WsSessionManager {
|
|
|
|
|
*/
|
|
|
|
|
public WebSocketSession getSession(String key) {
|
|
|
|
|
// 获得 session
|
|
|
|
|
return USER_SESSION_POOL.get(key);
|
|
|
|
|
return CLIENT_SESSION.get(key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取所有链接
|
|
|
|
|