Spring Boot集成WebSocket应首选STOMP模式实现消息路由,通过spring-boot-starter-websocket依赖、WebSocketMessageBrokerConfigurer配置端点与消息代理、@MessageMapping接收消息及SimpMessagingTemplate推送,并配合前端stomp.js完成连接、订阅与发送。

Spring Boot 集成 WebSocket 实现实时通信,核心是用好 spring-boot-starter-websocket,避开原生 API 的线程管理、Bean 注入、握手拦截等琐碎问题。它不是“加个依赖就能跑”,而是要明确走哪条技术路径:纯 WebSocket 处理器(适合设备直连、简单双向控制),还是基于 STOMP 的消息路由(适合聊天、广播、@提醒等业务场景)。下面分关键步骤讲清楚。
选对模式:STOMP 还是原生 WebSocket?
别一上来就写配置——先决定通信模型:
-
选 STOMP:当你要做群聊、私信、订阅特定主题(如
/topic/notice)、需要服务端主动推给某用户(@SendToUser)或某群组(@SendTo),STOMP 是更稳、更省事的选择。Spring 对它封装极深,消息格式统一,前端可用stomp.js直接 connect + subscribe。 -
选原生 WebSocket:适用于物联网设备接入、协议定制强(比如二进制帧、自定义指令头)、不需要复杂路由的场景。这时用
WebSocketHandler或@ServerEndpoint更直接,但消息解析、连接状态维护、广播逻辑都得自己写。
后端三步落地(以 STOMP 为例)
这是生产中最常用、扩展性最好的方式:
-
引入依赖:在
pom.xml中加spring-boot-starter-websocket。若用 STOMP,无需额外引入 stomp.js 服务端包——Spring 已内置;前端才需引入stomp.js和sockjs-client(用于兼容不支持 WebSocket 的老浏览器)。 -
配置类启用消息代理:创建配置类实现
WebSocketMessageBrokerConfigurer,开启@EnableWebSocketMessageBroker。关键动作有两步:
—registerStompEndpoints():注册握手端点(如/ws),并允许跨域、启用 SockJS 回退;
—configureMessageBroker():设置消息前缀,比如/topic用于广播、/user用于点对点。 -
编写控制器和推送逻辑:用
@MessageMapping接收客户端发来的消息(如@MessageMapping("/app/send"));用SimpMessagingTemplate主动推送,例如template.convertAndSend("/topic/notice", data)向所有订阅者广播,或template.convertAndSendToUser("uid123", "/queue/reply", msg)发给指定用户。
前端连接与通信(STOMP 常用写法)
前端不用手动处理 WebSocket 底层帧,用 stomp.js 就行:
- 先通过 SockJS 创建连接:
const socket = new SockJS('/ws'); - 再用 stomp.js 封装:
const stompClient = Stomp.over(socket); - 连接成功后,订阅主题:
stompClient.subscribe('/topic/notice', message => { console.log(JSON.parse(message.body)) }); - 发送消息:
stompClient.send('/app/send', {}, JSON.stringify({content: 'hello'}))。
必须考虑的生产细节
能连上不等于能用稳:
-
鉴权不能只靠前端传 token:在
HandshakeInterceptor中拦截握手请求,从 HTTP 头或参数里提取 JWT,校验后把用户信息存入attributes,后续处理器就能拿到当前用户 ID; -
心跳保活要配两端:前端 stomp.js 设置
heartbeat: {incoming: 10000, outgoing: 10000};服务端在配置中调用setHeartbeatValue(),避免 Nginx 或负载均衡器因空闲超时断连; -
集群部署需解决消息广播问题:单机没问题,多实例时
SimpMessagingTemplate默认只推给本机连接。要用 Redis 消息代理(redis://)或集成 Kafka,让各节点通过中间件转发消息。


















