spring boot 集成 websocket 实现实时聊天需建立持久双向通道,核心在于连接管理、消息分发、用户识别与容错兜底;须正确配置依赖与容器支持,线程安全存储连接,统一解析 json 消息,区分广播与点对点发送,并通过心跳、日志、异步处理及 redis 实现高可用扩展。

Spring Boot 集成 WebSocket 实现实时聊天,核心是建立持久、双向的通信通道,而不是靠轮询或单向推送。关键不在“能不能连上”,而在于连接怎么管、消息怎么发、用户怎么识别、异常怎么兜底。
依赖和基础配置必须到位
只加一个 starter 不够,还要确保底层容器支持(Spring Boot 默认内嵌 Tomcat 9+,已内置 WebSocket 支持):
- 在 pom.xml 中引入
spring-boot-starter-websocket(Spring Boot 3.x 使用 Jakarta EE API,无需额外 javax.websocket) - 如果用注解方式开发(如
@ServerEndpoint),需注册ServerEndpointExporterBean,否则注解不生效 - 若用 Spring 的 Handler 模式(继承
TextWebSocketHandler),则需配置WebSocketConfigurer并注册处理器路径
连接管理要线程安全且可追溯
每个客户端连接对应一个 Session,但不能直接存 Session 对象到普通集合里——它不是线程安全的,且断连后容易残留。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
CopyOnWriteArraySet<websocketserver></websocketserver>存活连接实例,避免并发修改异常 - 用
AtomicInteger统计在线人数,比普通 int 更可靠 - 路径参数(如
/api/websocket/{uid})建议提取为用户标识,用于精准广播或私聊 - 连接建立时(
@OnOpen)存 session、设 sid、更新计数;关闭时(@OnClose)清理、减计数、释放资源
消息收发得区分场景和格式
聊天不是只发字符串,得考虑:谁发的?发给谁?什么类型?要不要存库?
- 接收消息用
@OnMessage,建议统一解析 JSON(如 FastJson2 或 Jackson),转成标准Message对象 - 广播给所有人:遍历连接集合,跳过当前 sender,调用
session.getAsyncRemote().sendText() - 点对点发送:按
sid查找目标连接,再 send;找不到就返回“用户不在线” - 服务端主动通知(如上线提醒、系统公告),可在 onOpen 后立即调用 sendMessage
生产环境必须考虑容错和扩展
本地跑通不等于线上可用。真实聊天室会面临连接闪断、心跳缺失、消息堆积等问题。
- 前端需实现心跳机制(如每 30 秒发 ping),后端配合
@OnMessage处理 pong 或记录活跃时间 - 连接异常时(
@OnError)要记录日志,并主动 close session,防止句柄泄漏 - 高并发下,避免在 WebSocket 方法里做耗时操作(如查 DB、调远程接口),建议投递到线程池或消息队列
- 如需横向扩展(多节点部署),Session 状态不能只存在内存,得接入 Redis + 发布订阅来同步消息










