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("*")
相关推荐
武子康4 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
舒一笑5 小时前
我的开源项目-PandaCoder迎来史诗级大更新啦
后端·程序员·intellij idea
@昵称不存在6 小时前
Flask input 和datalist结合
后端·python·flask
zhuyasen6 小时前
Go 分布式任务和定时任务太难?sasynq 让异步任务从未如此简单
后端·go
东林牧之6 小时前
Django+celery异步:拿来即用,可移植性高
后端·python·django
何双新7 小时前
基于Tornado的WebSocket实时聊天系统:从零到一构建与解析
python·websocket·tornado
陈琦鹏7 小时前
轻松管理 WebSocket 连接!easy-websocket-client
前端·vue.js·websocket
超浪的晨7 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
AntBlack7 小时前
从小不学好 ,影刀 + ddddocr 实现图片验证码认证自动化
后端·python·计算机视觉
Pomelo_刘金8 小时前
Clean Architecture 整洁架构:借一只闹钟讲明白「整洁架构」的来龙去脉
后端·架构·rust