--- title: SpringBoot WebSocket使用 date: 2026-06-08 --- # 一、简介   [WebSocket API](https://docs.springjava.cn/spring-framework/reference/web/websocket/server.html) # 二、安装 ```xml org.springframework.boot spring-boot-starter-websocket ``` # 三、使用 ## 3.1 定义WebSocketHandler ```java @Component public class GenericWebSocketHandler extends TextWebSocketHandler { private static final Map SESSION_MAP = new ConcurrentHashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) { String userId = getUserId(session); SESSION_MAP.put(userId, session); log("用户连接成功:" + userId); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { String userId = getUserId(session); SESSION_MAP.remove(userId); log("用户断开连接:" + userId); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException { String payload = message.getPayload(); // 心跳处理 if ("PING".equalsIgnoreCase(payload)) { session.sendMessage(new TextMessage("PONG")); return; } // 普通消息(可按 JSON 协议扩展) log("收到消息:" + payload); session.sendMessage(new TextMessage("服务端已收到:" + payload)); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) { log("传输异常:" + exception.getMessage()); } /** 从 session 中获取用户标识(握手阶段放入) */ private String getUserId(WebSocketSession session) { return (String) session.getAttributes().getOrDefault("userId", session.getId()); } /** 单发 */ public void sendToUser(String userId, String msg) throws IOException { WebSocketSession session = SESSION_MAP.get(userId); if (session != null && session.isOpen()) { session.sendMessage(new TextMessage(msg)); } } /** 广播 */ public void broadcast(String msg) throws IOException { for (WebSocketSession session : SESSION_MAP.values()) { if (session.isOpen()) { session.sendMessage(new TextMessage(msg)); } } } /** 在线人数 */ public int onlineCount() { return SESSION_MAP.size(); } } ``` ## 3.2 定义HandshakeInterceptor ```java @Component public class GenericHandshakeInterceptor implements HandshakeInterceptor { /** * 握手前执行 */ @Override public boolean beforeHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) { // 从请求中URL中获取id // 例如:ws://localhost:8080/ws?userId=123,多个参数用&连接 String userId = servletRequest.getServletRequest().getParameter("userId"); if (userId == null) { // 返回 false → 握手失败 → 连接被拒绝 return false; } // 放入 attributes 中,方便下次获取 attributes.put("userId", userId); return true; } /** * 握手完成后执行(一般不用写) */ @Override public void afterHandshake( ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { } } ``` ## 3.3 配置WebSocketConfigurer ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Resource private GenericWebSocketHandler genericWebSocketHandler; @Resource private GenericHandshakeInterceptor genericHandshakeInterceptor; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(genericWebSocketHandler, "/ws") .addInterceptors(genericHandshakeInterceptor) .setAllowedOrigins("*"); } } ```   WebSocket连接地址:ip:port/ws?userId=123。 # 四、前端使用   参考:[useWebSocket](../Vue/VueUse.md)