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("*")
相关推荐
L2ncE几秒前
ES101系列09 | 运维、监控与性能优化
后端
CRMEB定制开发18 分钟前
PHP 支付系统扩展实战:从微信 / 支付宝到银联的多驱动架构设计
后端
史文豪18 分钟前
nacos2.5.1版本基于docker的自定义部署(适配人大金仓)
后端
aiopencode19 分钟前
移动端抓包指南:为什么真机HTTPS总是抓不到?(多工具对比 + Sniffmaster实战)
后端
追逐时光者30 分钟前
一款 .NET 开源、免费的适用于 Windows 下 PC 版微信/QQ/TIM的防撤回补丁(我已经看到了,撤回也没用了)!!
后端·.net
IT_陈寒42 分钟前
开发者必看!5个VSCode隐藏技巧让你的编码效率提升200% 🚀
前端·人工智能·后端
保持学习ing1 小时前
黑马Java面试笔记之 微服务篇(SpringCloud)
java·笔记·后端·阿里云·面试·负载均衡·springcloud
Chan161 小时前
【 SpringCloud | 微服务 网关 】
java·spring boot·后端·spring·spring cloud·微服务
Moment1 小时前
别小看 FAQ,用户体验和转化都离不开它!
前端·后端·面试
三分恶1 小时前
支付新手常犯的十个错误
后端