Skip to content

实时通信模块

youlai-boot 基于 WebSocket + STOMP 协议实现实时通信功能,支持服务端主动推送消息到前端,适用于用户在线状态管理、字典变更通知等场景。

设计目标

目标说明
实时推送服务端数据变更后立即通知前端,无需轮询
按需刷新通知前端清除缓存,下次使用时再加载,避免缓存穿透
多设备支持同一用户支持多设备同时在线
安全认证基于 JWT 的 WebSocket 连接认证
断线重连前端自动重连与订阅恢复

应用场景

场景说明通知方式
用户在线状态实时统计在线用户数,支持多设备登录广播 /topic/online-count
字典变更通知字典数据变更后通知前端清除缓存广播 /topic/dict

整体架构

核心组件

组件说明
WebSocketConfigSTOMP 端点配置,消息代理设置
WebSocketServiceImpl核心服务,用户在线管理与消息推送
UserSessionRegistry用户会话注册表,维护在线状态
WebSocketPublisher消息发布器,封装 STOMP 消息发送
DictChangeEvent字典变更事件 DTO

连接与认证流程

用户在线状态管理

数据结构

采用双 Map 结构实现高效查询:

映射表KeyValue用途
userSessionsMap用户名会话ID集合支持多设备登录,统计用户会话数
sessionDetailsMap会话ID会话详情快速定位用户,获取连接时间

在线用户统计

java
// 在线用户数(非会话数)
public int getOnlineUserCount() {
    return userSessionsMap.size();
}

// 在线会话总数(包含多设备)
public int getTotalSessionCount() {
    return sessionDetailsMap.size();
}

多设备登录处理

字典变更通知

设计思路

采用"通知清除,按需加载"策略,避免推送完整字典数据:

优势分析

策略实时性带宽消耗缓存一致性适用场景
推送完整数据数据量小
推送变更数据需增量更新
通知清除(本项目)通用场景
过期刷新数据实时性要求低

消息结构

后端 DTO

java
@Data
public class DictChangeEvent implements Serializable {
    /** 字典编码 */
    private String dictCode;
    /** 事件时间戳 */
    private long timestamp;
}

前端接口

typescript
interface DictChangeMessage {
  /** 字典编码 */
  dictCode: string;
  /** 时间戳 */
  timestamp: number;
}

字典变更流程

消息主题定义

主题类型说明消息体
/topic/dict广播字典变更通知DictChangeEvent
/topic/online-count广播在线用户数变更Integer
/topic/public广播系统公共消息TextMessage
/user/queue/messages点对点用户个人消息Object

前端集成

连接管理

typescript
// useStomp.ts - STOMP 连接管理
const stomp = useStomp({
  reconnectDelay: 15000,        // 重连延迟
  connectionTimeout: 10000,     // 连接超时
  maxReconnectAttempts: 3,      // 最大重连次数
  autoRestoreSubscriptions: true, // 自动恢复订阅
});

字典同步

typescript
// useDictSync.ts - 字典同步
const dictSync = useDictSync();

// 初始化(应用启动时)
dictSync.initialize();

// 注册回调
dictSync.onDictChange((message) => {
  console.log('字典已更新:', message.dictCode);
});

核心特性

特性说明
自动重连断线后自动重连,支持指数退避
订阅恢复重连后自动恢复之前的订阅
标签页可见性标签页激活时检查连接状态
Token 自动刷新连接时自动获取最新 Token

配置项

后端配置

yaml
# WebSocket 端点配置(前端环境变量)
VITE_APP_WS_ENDPOINT=ws://localhost:8080/ws

安全配置

yaml
security:
  # WebSocket 端点允许匿名访问(握手时校验 Token)
  ignore-urls:
    - /ws/**

定时任务

系统通过定时任务定期广播在线用户数,确保数据一致性:

java
@Scheduled(fixedRate = 60000) // 每分钟
public void broadcastOnlineCount() {
    webSocketService.notifyOnlineUsersChange();
}

最佳实践

后端

  1. 参数校验:所有公开方法进行参数校验
  2. 线程安全:使用 ConcurrentHashMap 保证线程安全
  3. 日志记录:连接/断开/消息推送记录日志
  4. 资源清理:用户断开时及时清理会话

前端

  1. 单例模式:WebSocket 连接使用单例,避免重复连接
  2. 按需订阅:只订阅必要的主题
  3. 错误处理:消息解析失败时记录日志,不影响主流程
  4. 缓存策略:收到通知后清除缓存,下次使用时再加载

相关文件

文件路径说明
platform/websocket/config/WebSocketConfig.javaWebSocket 配置类
platform/websocket/service/WebSocketService.java服务接口
platform/websocket/service/impl/WebSocketServiceImpl.java服务实现
platform/websocket/session/UserSessionRegistry.java会话注册表
platform/websocket/publisher/WebSocketPublisher.java消息发布器
platform/websocket/dto/DictChangeEvent.java字典变更事件
platform/websocket/dto/OnlineUserDTO.java在线用户 DTO
platform/websocket/topic/WebSocketTopics.java主题常量定义
vue3-element-admin/src/composables/websocket/useStomp.tsSTOMP 连接管理
vue3-element-admin/src/composables/websocket/useDictSync.ts字典同步

基于 MIT 许可发布