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("*")
相关推荐
海天胜景1 小时前
HTTP Error 500.31 - Failed to load ASP.NET Core runtime
后端·asp.net
海天胜景1 小时前
Asp.Net Core IIS发布后PUT、DELETE请求错误405
数据库·后端·asp.net
源码云商2 小时前
Spring Boot + Vue 实现在线视频教育平台
vue.js·spring boot·后端
2501_916013743 小时前
从一次被抄袭经历谈起:iOS App 安全保护实战
websocket·网络协议·tcp/ip·http·网络安全·https·udp
RunsenLIu4 小时前
基于Django实现的篮球论坛管理系统
后端·python·django
HelloZheQ6 小时前
Go:简洁高效,构建现代应用的利器
开发语言·后端·golang
caihuayuan56 小时前
[数据库之十四] 数据库索引之位图索引
java·大数据·spring boot·后端·课程设计
风象南7 小时前
Redis中6种缓存更新策略
redis·后端
程序员Bears8 小时前
Django进阶:用户认证、REST API与Celery异步任务全解析
后端·python·django
非晓为骁8 小时前
【Go】优化文件下载处理:从多级复制到零拷贝流式处理
开发语言·后端·性能优化·golang·零拷贝