WebSocket 入门案例(ServerEndpointExporter方式)

179 阅读2分钟

1、编写客户端页面

 <!DOCTYPE html>
 <html lang="en">
 ​
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>WebSocket 入门案例</title>
 </head>
 ​
 <body>
     <input id="text" type="text" placeholder="请输入内容" />
     <button onclick="send()">发送消息</button>
     <button onclick="closeWebSocket()">关闭连接</button>
     <div id="message">
     </div>
 </body>
 ​
 <script type="text/javascript">
     var websocket = null;
     var clientId = Math.random().toString(36).substr(2);
 ​
     // 判断当前浏览器是否支持WebSocket
     if ('WebSocket' in window) {
         // 连接WebSocket节点
         websocket = new WebSocket("ws://localhost:8080/ws/" + clientId);
     }
     else {
         alert('Not support websocket')
     }
 ​
     // 连接发生错误的回调方法
     websocket.onerror = function () {
         setMessageInnerHTML("error");
     };
 ​
     // 连接成功建立的回调方法
     websocket.onopen = function () {
         setMessageInnerHTML("连接成功");
     }
 ​
     // 接收到消息的回调方法
     websocket.onmessage = function (event) {
         setMessageInnerHTML(event.data);
     }
 ​
     // 连接关闭的回调方法
     websocket.onclose = function () {
         setMessageInnerHTML("close");
     }
 ​
     // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
     window.onbeforeunload = function () {
         websocket.close();
     }
 ​
     // 将消息显示在网页上
     function setMessageInnerHTML(innerHTML) {
         document.getElementById('message').innerHTML += innerHTML + '<br/>';
     }
 ​
     // 发送消息
     function send() {
         var message = document.getElementById('text').value;
         websocket.send(message);
     }
 ​
     // 关闭连接
     function closeWebSocket() {
         websocket.close();
     }
 </script>
 ​
 </html>

2、导入依赖

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-websocket</artifactId>
     <version>3.4.3</version>
 </dependency>

3、编写服务端组件

 /**
  * WebSocket服务
  */
 @Component
 @ServerEndpoint("/ws/{sid}")
 public class WebSocketServer {
 ​
     //存放会话对象
     private static Map<String, Session> sessionMap = new HashMap();
 ​
     /**
      * 连接建立成功调用的方法
      */
     @OnOpen
     public void onOpen(Session session, @PathParam("sid") String sid) {
         System.out.println("客户端:" + sid + "建立连接");
         sessionMap.put(sid, session);
     }
 ​
     /**
      * 收到客户端消息后调用的方法
      *
      * @param message 客户端发送过来的消息
      */
     @OnMessage
     public void onMessage(String message, @PathParam("sid") String sid) {
         System.out.println("收到来自客户端:" + sid + "的信息:" + message);
     }
 ​
     /**
      * 连接关闭调用的方法
      *
      * @param sid
      */
     @OnClose
     public void onClose(@PathParam("sid") String sid) {
         System.out.println("连接断开:" + sid);
         sessionMap.remove(sid);
     }
 ​
     /**
      * 向客户端群发消息
      *
      * @param message
      */
     public void sendToAllClient(String message) {
         Collection<Session> sessions = sessionMap.values();
         for (Session session : sessions) {
             try {
                 //服务器向客户端发送消息
                 session.getBasicRemote().sendText(message);
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
     }
 }

4、编写配置类,注册服务端组件

 /**
  * WebSocket配置类,用于注册WebSocket的Bean
  */
 @Configuration
 public class WebSocketConfiguration {
 ​
     @Bean
     public ServerEndpointExporter serverEndpointExporter() {
         return new ServerEndpointExporter();
     }
 }

5、编写定时任务类

作用:定时向客户端发送消息

 @Component
 public class WebSocketTask {
     @Autowired
     private WebSocketServer webSocketServer;
 ​
     /**
      * 通过WebSocket每隔5秒向客户端发送消息
      */
     @Scheduled(cron = "0/5 * * * * ?")
     public void sendMessageToClient() {
         webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
     }
 }

6、启动服务,打开客户端页面查看效果

image-20250319092306261.png

image-20250319092339936.png