在 Spring Boot 应用中使用 @ServerEndpoint
实现 WebSocket 通信是一种常见方式。@ServerEndpoint
是 Java EE 提供的注解,通常需要配合 javax.websocket API 使用。Spring Boot 本身并不直接管理 @ServerEndpoint
,但可以通过一些技巧让它与 Spring 环境集成,同时实现客户端识别和管理。
本文将介绍如何在 Spring Boot 应用中使用 @ServerEndpoint
注解实现 WebSocket 通信,并实现对客户端的识别与管理。
项目依赖配置 首先,在 pom.xml
中添加必要的依赖:
1 2 3 4 5 6 7 <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter-websocket</artifactId > </dependency > </dependencies >
这些依赖确保了 Spring Boot 应用能够支持 WebSocket 通信。
WebSocket 配置类 为了使 @ServerEndpoint
注解生效,需要配置 ServerEndpointExporter
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 (); } }
注意:如果使用外部的 Tomcat 容器部署应用,则不需要配置 ServerEndpointExporter
。
创建 WebSocket 服务端端点 使用 @ServerEndpoint
注解定义 WebSocket 端点,并实现客户端的识别与管理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 import javax.websocket.*;import javax.websocket.server.PathParam;import javax.websocket.server.ServerEndpoint;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.atomic.AtomicInteger;@ServerEndpoint("/ws/{clientId}") public class WebSocketServer { private static AtomicInteger onlineCount = new AtomicInteger (0 ); private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap <>(); private String clientId; @OnOpen public void onOpen (Session session, @PathParam("clientId") String clientId) { this .clientId = clientId; sessionMap.put(clientId, session); onlineCount.incrementAndGet(); System.out.println("客户端连接: " + clientId + ",当前在线人数为: " + onlineCount.get()); } @OnClose public void onClose () { sessionMap.remove(clientId); onlineCount.decrementAndGet(); System.out.println("客户端断开连接: " + clientId + ",当前在线人数为: " + onlineCount.get()); } @OnMessage public void onMessage (String message, Session session) { System.out.println("收到客户端(" + clientId + ")消息: " + message); sendMessageToClient(clientId, "服务端收到: " + message); } @OnError public void onError (Session session, Throwable error) { System.err.println("客户端(" + clientId + ")发生错误: " + error.getMessage()); } public void sendMessageToClient (String clientId, String message) { Session session = sessionMap.get(clientId); if (session != null && session.isOpen()) { session.getAsyncRemote().sendText(message); } } public void broadcastMessage (String message) { sessionMap.forEach((clientId, session) -> { if (session.isOpen()) { session.getAsyncRemote().sendText(message); } }); } }
在上述代码中,@ServerEndpoint("/ws/{clientId}")
表示客户端连接的地址,其中 {clientId}
用于标识客户端。通过 ConcurrentHashMap
存储客户端的 Session
,实现对客户端的识别与管理。
总结 通过上述配置和代码实现,我们在 Spring Boot 应用中成功集成了 WebSocket,并使用 @ServerEndpoint
注解实现了客户端的识别与管理。这种方式适用于需要实时通信的应用场景,如聊天室、通知系统等。
如果您需要进一步的功能扩展,如心跳检测、消息持久化等,可以在此基础上进行开发。