SpringBoot3整合WebSocket详细指南
1. 什么是WebSocket?
WebSocket 是一种网络通信协议,提供全双工通信通道,使服务器可以主动向客户端推送数据。与传统的 HTTP 请求-响应模式不同,WebSocket 在建立连接后,允许服务器和客户端之间进行双向实时通信。
主要特点:
- 建立在 TCP 协议之上
- 与 HTTP 协议有良好的兼容性
- 数据格式轻量,性能开销小
- 可以发送文本和二进制数据
- 没有同源限制,客户端可以与任意服务器通信
2. 环境准备
2.1 项目依赖
首先在pom.xml
中添加必要的依赖:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.2.5</version> </parent> <dependencies> <!-- WebSocket依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <!-- Web依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Lombok依赖(可选) --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>
3. WebSocket配置
3.1 WebSocket配置类
创建 WebSocket 配置类,启用 WebSocket 功能并注册端点:
package com.coderjia.boot3websocket.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; /** * @author CoderJia * @create 2024/12/15 下午 08:11 * @Description **/ @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler(), "/websocket") .setAllowedOrigins("*"); // 允许跨域访问 } @Bean public WebSocketHandler webSocketHandler() { // 使用自定义的WebSocket处理器 return new CustomWebSocketHandler(); } }
3.2 自定义WebSocket处理器
创建自定义的 WebSocket 处理器,处理消息收发:
package com.coderjia.boot3websocket.config; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author CoderJia * @create 2024/12/15 下午 08:21 * @Description **/ @Component @Slf4j public class CustomWebSocketHandler extends TextWebSocketHandler { // 用于存储WebSocket会话 private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { String sessionId = session.getId(); sessions.put(sessionId, session); log.info("WebSocket连接建立成功:{}", sessionId); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); log.info("收到消息:{}", payload); // 发送回复消息 String replyMessage = "服务器收到消息:" + payload; session.sendMessage(new TextMessage(replyMessage)); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { String sessionId = session.getId(); sessions.remove(sessionId); log.info("WebSocket连接关闭:{}", sessionId); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { log.error("WebSocket传输错误", exception); } // 广播消息给所有连接的客户端 public void broadcastMessage(String message) { sessions.values().forEach(session -> { try { session.sendMessage(new TextMessage(message)); } catch (IOException e) { log.error("广播消息失败", e); } }); } }
4. 控制器
创建 REST 控制器,用于测试消息广播:
@RestController @RequestMapping("/api/websocket") public class WebSocketController { private final CustomWebSocketHandler webSocketHandler; public WebSocketController(CustomWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @PostMapping("/broadcast") public ResponseEntity<String> broadcastMessage(@RequestBody String message) { webSocketHandler.broadcastMessage(message); return ResponseEntity.ok("消息广播成功"); } }
5. 前端实现
5.1 HTML页面
<!DOCTYPE html> <html lang="en"> <head> <title>WebSocket测试</title> </head> <body> <div> <h2>WebSocket测试页面</h2> <div> <input type="text" id="messageInput" placeholder="输入消息"> <button onclick="sendMessage()">发送</button> </div> <div id="messages" style="margin-top: 20px;"></div> </div> <script> let ws = null; function connect() { ws = new WebSocket('ws://localhost:8080/websocket'); ws.onopen = function() { console.log('WebSocket连接已建立'); appendMessage('系统消息:连接已建立'); }; ws.onmessage = function(event) { appendMessage('收到消息:' + event.data); }; ws.onclose = function() { console.log('WebSocket连接已关闭'); appendMessage('系统消息:连接已关闭'); }; ws.onerror = function(error) { console.error('WebSocket错误:', error); appendMessage('系统消息:连接发生错误'); }; } function sendMessage() { const messageInput = document.getElementById('messageInput'); const message = messageInput.value; if (ws && message) { ws.send(message); appendMessage('发送消息:' + message); messageInput.value = ''; } } function appendMessage(message) { const messagesDiv = document.getElementById('messages'); const messageElement = document.createElement('div'); messageElement.textContent = message; messagesDiv.appendChild(messageElement); } // 页面加载完成后连接WebSocket window.onload = connect; </script> </body> </html>
6. 测试WebSocket功能
- 启动 SpringBoot 应用
- 打开多个浏览器窗口访问 HTML 页面
- 在任意窗口发送消息,观察其他窗口是否收到消息
- 使用 POST 请求测试广播功能:
curl -X POST http://localhost:8080/api/websocket/broadcast \ -H "Content-Type: text/plain" \ -d "这是一条广播消息"
7. 进阶功能
7.1 心跳检测
为了保持WebSocket连接的稳定性,可以实现心跳机制:
@Scheduled(fixedRate = 10000) // 每10秒发送一次心跳,需要启动类或配置类上添加@EnableScheduling public void sendHeartbeat() { String heartbeat = "heartbeat"; sessions.values().forEach(session -> { try { session.sendMessage(new TextMessage(heartbeat)); } catch (IOException e) { log.error("发送心跳消息失败", e); } }); }
7.2 消息重试机制
当消息发送失败时,实现重试机制:
public void sendMessageWithRetry(WebSocketSession session, String message, int maxRetries) { int retryCount = 0; while (retryCount < maxRetries) { try { session.sendMessage(new TextMessage(message)); return; } catch (IOException e) { retryCount++; log.error("消息发送失败,尝试重试 {}/{}", retryCount, maxRetries); try { Thread.sleep(1000); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); break; } } } log.error("消息发送失败,达到最大重试次数"); }
8. 注意事项
连接管理
- 及时清理断开的连接
- 实现最大连接数限制
- 考虑使用连接池管理WebSocket连接
安全性
- 实现用户认证
- 添加消息加密
- 设置适当的跨域策略
性能优化
- 使用消息队列处理大量消息
- 实现消息压缩
- 控制消息大小
错误处理
- 完善异常处理机制
- 实现日志记录
- 添加监控告警
9. 总结
SpringBoot 3 整合 WebSocket 提供了一种高效的实时通信解决方案。通过本文的配置和示例,你可以快速实现:
- WebSocket服务器端配置
- 客户端连接管理
- 消息收发处理
- 广播功能
- 心跳检测
- 错误处理
这些功能可以作为构建实时应用的基础,如在线聊天、实时数据推送、游戏等场景。根据具体需求,你可以在此基础上扩展更多功能。
参考资料
到此这篇关于SpringBoot3整合WebSocket指南的文章就介绍到这了,更多相关SpringBoot3整合WebSocket内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
- SpringBoot3集成WebSocket的全过程
- SpringBoot整合Netty+Websocket实现消息推送的示例代码
- springboot整合websocket后启动报错(javax.websocket.server.ServerContainer not available)
- SpringBoot 整合WebSocket 前端 uniapp 访问的详细方法
- Springboot整合WebSocket实战教程
- SpringBoot整合WebSocket的客户端和服务端的实现代码
- SpringBoot整合Netty实现WebSocket的示例代码
- springboot整合websocket最基础入门使用教程详解
- 通过实例讲解springboot整合WebSocket
最新评论