4.3 KiB
4.3 KiB
title, date
| title | date |
|---|---|
| SpringBoot WebSocket简介和使用 | 2026-06-08 |
一、简介
二、安装
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
三、使用
3.1 定义WebSocketHandler
@Component
public class GenericWebSocketHandler extends TextWebSocketHandler {
private static final Map<String, WebSocketSession> 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
@Component
public class GenericHandshakeInterceptor implements HandshakeInterceptor {
/**
* 握手前执行
*/
@Override
public boolean beforeHandshake(
ServerHttpRequest request,
ServerHttpResponse response,
WebSocketHandler wsHandler,
Map<String, Object> 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
@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