HoRain云--SpringBoot WebSocket实战指南
本文介绍了在Spring Boot中集成WebSocket的两种主要方式。第一种是使用STOMP子协议,适合常见的发布-订阅场景,配置简单,前端可使用STOMP客户端库。第二种是原生WebSocket API,提供更底层的控制,适合自定义协议需求,但需要自行管理会话。文章对比了两种方式的特性、适用场景和实现步骤,并给出了安全性、性能和扩展性等进阶考虑。开发者可根据项目需求选择合适的方式,快速构建实

🎬 HoRain 云小助手:个人主页
⛺️生活的理想,就是为了理想的生活!
⛳️ 推荐
前些天发现了一个超棒的服务器购买网站,性价比超高,大内存超划算!忍不住分享一下给大家。点击跳转到网站。
目录

在 Spring Boot 中集成 WebSocket 来构建实时应用非常方便。下面是一个清晰的指南,帮助你理解两种主要的实现方式及其核心步骤。
🧩 两种实现方式概览
Spring Boot 集成 WebSocket 主要有两种方式,其核心区别在于协议的层级不同。下面的流程图可以帮你快速了解这两种路径以及如何选择。
flowchart TD
A[开始:集成Spring Boot WebSocket] --> B{选择实现方式}
B -->|需要更高级消息模式<br>(如发布-订阅)| C[方式一:使用STOMP]
B -->|需要底层控制<br>或自定义协议| D[方式二:使用原生WebSocket API<br>(或SockJS)]
C --> E[步骤:配置消息代理];
E --> F[步骤:创建消息控制器];
F --> G[前端:使用STOMP客户端];
D --> H[步骤:实现WebSocketHandler];
H --> I[步骤:注册处理器];
I --> J[前端:使用原生WebSocket<br>或SockJS];
G & J --> K[完成集成,实现实时通信]
简单来说:
-
如果你希望像使用消息队列(如发布-订阅)一样处理实时消息,或者前端希望使用更简单的消息模型,STOMP 是不错的选择。
-
如果你需要直接控制通信细节,或者与使用自定义协议的现有系统集成,那么原生WebSocket API 更适合你。
接下来,我们看看这两种方式的具体步骤。
🔧 方式一:使用STOMP子协议
STOMP 提供了一个基于帧的协议,非常适合常见的消息推送场景,如聊天室、实时通知 。
-
添加依赖
在
pom.xml中添加 Spring Boot 对 WebSocket 和 STOMP 的支持(通常包含在spring-boot-starter-websocket中)。 -
配置STOMP与消息代理
创建配置类,启用基于STOMP的消息代理。代理负责将消息路由到订阅了特定目的地的客户端 。
@Configuration @EnableWebSocketMessageBroker // 启用STOMP消息代理 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 注册STOMP端点,客户端将连接到此端点,并允许使用SockJS作为备选方案 registry.addEndpoint("/ws-endpoint").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry config) { // 启用一个简单的基于内存的消息代理,负责将消息路由到以"/topic"开头的目的地 config.enableSimpleBroker("/topic"); // 设置应用前缀,所有目的地以"/app"开头的消息都会被路由到@MessageMapping注解的方法 config.setApplicationDestinationPrefixes("/app"); } } -
创建消息控制器
像编写Spring MVC控制器一样处理客户端发送的消息 。
@Controller public class MessagingController { // 处理发送到"/app/send-message"目的地的消息 @MessageMapping("/send-message") // 将返回值广播给所有订阅了"/topic/messages"的客户端 @SendTo("/topic/messages") public String handleMessage(String message) { // 处理消息,这里简单返回 return "服务器回复: " + message; } } -
前端连接与通信
使用 STOMP 客户端库(如
stomp.js)连接和通信 。// 使用SockJS建立连接,再使用STOMP协议 var socket = new SockJS('/ws-endpoint'); var stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { // 订阅目的地为"/topic/messages"的消息 stompClient.subscribe('/topic/messages', function(message) { console.log('收到消息: ' + message.body); }); // 发送消息到"/app/send-message" stompClient.send("/app/send-message", {}, "你好,服务器!"); });
⚙️ 方式二:使用原生WebSocket API
这种方式更底层,适合需要精细控制通信过程或使用自定义协议的场景 。
-
添加依赖
同样需要在
pom.xml中添加spring-boot-starter-websocket依赖 。 -
实现WebSocket处理器
创建一个类继承
TextWebSocketHandler或BinaryWebSocketHandler,处理文本或二进制消息 。@Component public class MyWebSocketHandler extends TextWebSocketHandler { private static final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); // 新连接建立,保存session session.sendMessage(new TextMessage("连接成功")); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); // 获取客户端消息 // 处理消息,例如广播给所有连接 for (WebSocketSession s : sessions) { if (s.isOpen()) { s.sendMessage(new TextMessage("收到: " + payload)); } } } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); // 连接关闭,移除session } } -
注册WebSocket处理器
通过配置类将处理器注册到特定路径 。
@Configuration @EnableWebSocket // 启用WebSocket支持(非STOMP) public class WebSocketConfig implements WebSocketConfigurer { @Autowired private MyWebSocketHandler myWebSocketHandler; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // 将自定义的处理器注册到路径"/ws" registry.addHandler(myWebSocketHandler, "/ws").setAllowedOrigins("*"); } } -
前端连接
使用浏览器原生 WebSocket API 连接 。
var socket = new WebSocket('ws://localhost:8080/ws'); socket.onopen = function(event) { console.log('连接已建立'); }; socket.onmessage = function(event) { console.log('收到消息: ' + event.data); }; socket.send('你好!'); // 发送消息
🚀 进阶考虑与最佳实践
在实际项目中,除了基本功能,还需考虑以下几点:
-
会话管理:在原生API方式中,需要使用线程安全的集合(如
ConcurrentHashMap)管理WebSocketSession,以便向特定客户端发送消息或实现广播 。 -
心跳与健康检查:实现心跳机制(如定时发送Ping/Pong帧)来检测和清理僵死连接 。
-
安全性:
-
身份验证与授权:可以在握手阶段(如通过拦截器
HandshakeInterceptor)或连接建立后验证用户身份 。结合 Spring Security 可以更好地保护 WebSocket 端点 。 -
跨域控制:使用
setAllowedOrigins("*")允许所有来源,但在生产环境中应限制为信任的域名 。 -
使用WSS:在生产环境使用
wss://(WebSocket Secure)来加密通信 。
-
-
处理不支持WebSocket的客户端:使用 SockJS 作为备选方案,在不支持 WebSocket 的浏览器中模拟 WebSocket 行为 。
-
性能与扩展:
-
对于高并发场景,考虑使用外部消息代理(如 RabbitMQ、Redis)替代简单的内存代理,以支持集群部署 。
-
使用
@Async支持异步处理,避免阻塞消息线程 。
-
💎 核心对比与选择
|
特性 |
STOMP over WebSocket |
原生 WebSocket API |
|---|---|---|
|
协议层级 |
更高,基于帧的协议 |
较低,直接基于TCP |
|
适用场景 |
常见的发布-订阅、点对点消息 |
需要精细控制、自定义协议 |
|
编程模型 |
类似消息控制器,更声明式 |
处理器接口,更命令式 |
|
前端集成 |
通常需STOMP客户端库(如stomp.js) |
使用浏览器原生WebSocket API |
|
会话管理 |
通常由框架和消息代理协助管理 |
需自行管理WebSocketSession |
希望这份指南能帮助你顺利地在 Spring Boot 项目中集成 WebSocket!如果你在特定步骤上遇到问题,或者想了解更深入的最佳实践,比如如何结合特定的消息队列,欢迎随时提出。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
更多推荐



所有评论(0)