SpringBoot 集成WebSocket 实现客户端服务器端长连接 仅本地实现
使用Maven导入Maven依赖
Maven仓库或直接复制下面的pom文件
该依赖包含springboot集成WebSocket的核心包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
自定义Spring配置类
用于配置 WebSocket 的支持。代码的核心目的是启用服务器端 WebSocket 的功能。
在Spring Boot中,ServerEndpointExporter是一个非常重要的Bean,
- 因为它负责扫描和注册所有带有@ServerEndpoint注解的WebSocket端点。
- 以下是该Bean的作用及其配置的详细说明:
- 作用
- 扫描带有@ServerEndpoint注解的类:ServerEndpointExporter会自动扫描应用程序中的所有@ServerEndpoint注解的类,并将它们注册为WebSocket端点。
- 注册WebSocket端点:它将找到的WebSocket端点注册到默认的容器(如Tomcat、Jetty、Undertow等),使这些端点能够接受和处理WebSocket连接和消息。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
@Configuration标记这个类是一个配置类,Spring 容器会识别它并将其用于应用程序上下文的初始化。
@Bean将方法返回的 ServerEndpointExporter 实例注册为一个 Spring Bean,供容器管理。
ServerEndpointExporter它是 Spring 提供的一个 WebSocket 配置类,主要功能是扫描并注册所有使用 @ServerEndpoint 注解的 WebSocket 端点(Endpoints)。换句话说ServerEndpointExporter 会自动处理带有 @ServerEndpoint 注解的类,使它们能够接受 WebSocket 连接。
具体WebSocket实现
import cn.hutool.json.JSONUtil;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
@Component
@ServerEndpoint(value = "/websocket/{userId}")
public class WebSocket {
private static ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
//实例一个session,这个session是websocket的session
private Session session;
//新增一个方法用于主动向客户端发送消息
public static void sendMessage(Object message, String userId) {
WebSocket webSocket = webSocketMap.get(userId);
if (webSocket != null) {
try {
webSocket.session.getBasicRemote().sendText(JSONUtil.toJsonStr(message));
System.out.println("【websocket消息】发送消息成功,用户="+userId+",消息内容"+message.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static ConcurrentHashMap<String, WebSocket> getWebSocketMap() {
return webSocketMap;
}
public static void setWebSocketMap(ConcurrentHashMap<String, WebSocket> webSocketMap) {
WebSocket.webSocketMap = webSocketMap;
}
//前端请求时一个websocket时
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
System.out.println("【WebSocket消息】onOpen 被调用,用户ID: " + userId);
this.session = session;
webSocketMap.put(userId, this);
sendMessage("CONNECT_SUCCESS", userId);
System.out.println("【websocket消息】有新的连接,连接id"+userId);
}
//前端关闭时一个websocket时
@OnClose
public void onClose(@PathParam("userId") String userId) {
webSocketMap.remove(userId);
System.out.println("【websocket消息】连接断开,总数:"+ webSocketMap.size());
}
//前端向后端发送消息
@OnMessage
public String onMessage(String message) {
if (!message.equals("ping")) {
System.out.println("【websocket消息】收到客户端发来的消息:"+message);
}
return "你好!";
}
}
主启动类上加上 @EnableWebSocket
@SpringBootApplication
@EnableWebSocket
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}