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("*")
相关推荐
uzong2 小时前
技术故障复盘模版
后端
GetcharZp2 小时前
基于 Dify + 通义千问的多模态大模型 搭建发票识别 Agent
后端·llm·agent
桦说编程2 小时前
Java 中如何创建不可变类型
java·后端·函数式编程
IT毕设实战小研3 小时前
基于Spring Boot 4s店车辆管理系统 租车管理系统 停车位管理系统 智慧车辆管理系统
java·开发语言·spring boot·后端·spring·毕业设计·课程设计
wyiyiyi3 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
阿华的代码王国4 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
Jimmy4 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
AntBlack5 小时前
不当韭菜V1.1 :增强能力 ,辅助构建自己的交易规则
后端·python·pyqt
bobz9655 小时前
pip install 已经不再安全
后端
寻月隐君5 小时前
硬核实战:从零到一,用 Rust 和 Axum 构建高性能聊天服务后端
后端·rust·github