mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2026-06-27 16:14:31 +00:00
fix 修复 push 模块 sse/ws 浏览器多标签页互挤掉线问题
This commit is contained in:
+5
@@ -31,4 +31,9 @@ public interface MessageConstants {
|
||||
* 心跳响应标识
|
||||
*/
|
||||
String PONG = "pong";
|
||||
|
||||
/**
|
||||
* 同一 token 的新连接替换旧连接时发送给旧连接的控制消息。
|
||||
*/
|
||||
String KICKED = "kicked";
|
||||
}
|
||||
|
||||
+16
@@ -65,6 +65,7 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
// 关闭已存在的SseEmitter,防止超过最大连接数
|
||||
SseEmitter oldEmitter = emitters.remove(token);
|
||||
if (oldEmitter != null) {
|
||||
sendKickedMessage(oldEmitter);
|
||||
oldEmitter.complete();
|
||||
}
|
||||
|
||||
@@ -103,6 +104,21 @@ public class SseEmitterSessionManager implements PushSessionManager {
|
||||
return emitter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知旧连接已被同 token 新连接替换。
|
||||
*
|
||||
* @param emitter 旧 SSE 连接
|
||||
*/
|
||||
private void sendKickedMessage(SseEmitter emitter) {
|
||||
try {
|
||||
emitter.send(SseEmitter.event()
|
||||
.name("message")
|
||||
.data(MessageConstants.KICKED));
|
||||
} catch (Exception ignore) {
|
||||
// 旧连接可能已断开,忽略通知失败
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开指定用户的 SSE 连接
|
||||
*
|
||||
|
||||
+14
@@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.ThreadUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.push.constant.MessageConstants;
|
||||
import org.dromara.common.push.dto.PushDTO;
|
||||
import org.dromara.common.push.properties.MessageProperties;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
@@ -61,6 +62,7 @@ public class WebSocketSessionManager implements PushSessionManager {
|
||||
Map<String, WebSocketSession> sessions = USER_TOKEN_SESSIONS.computeIfAbsent(userId, key -> new ConcurrentHashMap<>());
|
||||
// 移除并关闭旧的同token会话,避免重复连接
|
||||
WebSocketSession oldSession = sessions.remove(token);
|
||||
sendKickedMessage(oldSession);
|
||||
closeSession(oldSession, CloseStatus.NORMAL);
|
||||
// 存储新会话
|
||||
sessions.put(token, session);
|
||||
@@ -129,6 +131,18 @@ public class WebSocketSessionManager implements PushSessionManager {
|
||||
toRemoveUsers.forEach(USER_TOKEN_SESSIONS::remove);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知旧连接已被同 token 新连接替换。
|
||||
*
|
||||
* @param session 旧 WebSocket 会话
|
||||
*/
|
||||
private void sendKickedMessage(WebSocketSession session) {
|
||||
if (session == null || !session.isOpen()) {
|
||||
return;
|
||||
}
|
||||
sendMessage(session, MessageConstants.KICKED);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅消息通道
|
||||
* 注册消息消费者,监听Redis消息推送
|
||||
|
||||
Reference in New Issue
Block a user