WebSocket 入门案例(基于Handler的方式)

1、导入依赖

xml 复制代码
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-websocket</artifactId>
     <version>3.4.3</version>
 </dependency>

2、编写WebSocket配置类

创建配置类启用WebSocket并注册处理器:

java 复制代码
 @Configuration
 @EnableWebSocket
 public class WebSocketConfig implements WebSocketConfigurer {
     private final MyWebSocketHandler handler;
 ​
     // 构造器注入自定义Handler
     public WebSocketConfig(MyWebSocketHandler handler) {
         this.handler = handler;
     }
 ​
     @Override
     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
         registry.addHandler(handler, "/ws/{sid}")  // 定义WebSocket端点路径
                 .setAllowedOrigins("*");      // 允许跨域访问
     }
 }

3、自定义WebSocket处理器

继承TextWebSocketHandler实现消息处理逻辑:

java 复制代码
 @Component
 public class MyWebSocketHandler extends TextWebSocketHandler {
     private final MyService service;
 ​
     // 注入业务Service
     public MyWebSocketHandler(MyService service) {
         this.service = service;
     }
 ​
     // 存放会话对象
     private final HashMap<String, WebSocketSession> sessionMap = new HashMap<>();
 ​
     @OnOpen
     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
         // 从URI路径中提取sid参数
         String path = Objects.requireNonNull(session.getUri()).getPath(); // 示例:/ws/pknqmqttai8
         String sid = path.substring(path.lastIndexOf('/') + 1);
 ​
         sessionMap.put(sid, session);
         session.getAttributes().put("CLIENT_ID", sid); // 存入会话属性
     }
 ​
     @Override
     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
         // 处理客户端消息
         String payload = message.getPayload();
         String response = service.processMessage(payload);  // 调用业务逻辑
 ​
         // 返回处理结果(谁给服务器发,服务器就给谁发)
         session.sendMessage(new TextMessage("服务端响应: " + response));
 ​
         // 群发(不管谁给服务器发,服务器都给所有客户端发)
         sendMessageToAll("服务端广播: " + response);
     }
 ​
     @Override
     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
         String clientId = (String) session.getAttributes().get("CLIENT_ID");
         sessionMap.remove(clientId);
     }
 ​
     public void sendMessageToAll(String message) {
         // 获取所有会话
         Collection<WebSocketSession> sessions = sessionMap.values();
         for (WebSocketSession session : sessions) {
             try {
                 // 发送消息
                 session.sendMessage(new TextMessage(message));
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 }

4、业务服务层(Service)

typescript 复制代码
 public interface MyService {
     String processMessage(String message);
 }
 ​
 ​
 @Service
 public class MyServiceImpl implements MyService {
     public String processMessage(String message) {
         // 示例:处理消息并返回结果
         return "已处理消息: " + message.toUpperCase();
     }
 }

5、前端测试页面

HTML页面示例(放置于resources/static目录):

xml 复制代码
 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>websocket 入门案例(新)</title>
 </head>
 <body>
 ​
 <input type="text" id="message" placeholder="输入消息">
 <button onclick="sendMessage()">发送</button>
 <button onclick="closeWebSocket()">关闭连接</button>
 <div id="output"></div>
 ​
 <script>
     let socket = null
     let clientId = Math.random().toString(36).substring(2)
 ​
     // 判断当前浏览器是否支持WebSocket
     if ('WebSocket' in window) {
         // 连接WebSocket节点
         socket = new WebSocket('ws://localhost:8080/ws/' + clientId)
     } else {
         alert('Not support websocket')
     }
 ​
     socket.onerror = () => {
         console.log("连接错误")
     }
 ​
     socket.onopen = () => {
         console.log("连接已建立")
     }
 ​
     socket.onmessage = (event) => {
         document.getElementById('output').innerHTML += `<p>收到: ${event.data}</p>`
     }
 ​
     socket.onclose = () => {
         console.log("连接已关闭...")
     }
 ​
     function sendMessage() {
         const msg = document.getElementById('message').value
         socket.send(msg)
     }
 ​
     function closeWebSocket() {
         socket.close()
     }
 </script>
 </body>
 </html>

6、运行与测试

  1. 启动Spring Boot应用,访问http://localhost:8080进入测试页面。
  2. 输入消息后点击发送,观察服务端返回的响应。
  3. 服务端控制台会打印接收到的消息日志。

7、注意事项

  • 跨域问题 :生产环境需配置具体域名而非setAllowedOrigins("*")
相关推荐
程序员侠客行35 分钟前
Mybatis连接池实现及池化模式
java·后端·架构·mybatis
Honmaple40 分钟前
QMD (Quarto Markdown) 搭建与使用指南
后端
PP东1 小时前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
invicinble1 小时前
springboot的核心实现机制原理
java·spring boot·后端
全栈老石2 小时前
Python 异步生存手册:给被 JS async/await 宠坏的全栈工程师
后端·python
space62123272 小时前
在SpringBoot项目中集成MongoDB
spring boot·后端·mongodb
默默前行的虫虫2 小时前
解决EMQX WebSocket连接不稳定及优化WS配置提升稳定性?
websocket
Tony Bai2 小时前
再见,丑陋的 container/heap!Go 泛型堆 heap/v2 提案解析
开发语言·后端·golang
寻找奶酪的mouse3 小时前
30岁技术人对职业和生活的思考
前端·后端·年终总结
梦想很大很大3 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go