在 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 注解实现了客户端的识别与管理。这种方式适用于需要实时通信的应用场景,如聊天室、通知系统等。
如果您需要进一步的功能扩展,如心跳检测、消息持久化等,可以在此基础上进行开发。