websocket

1、pom.xml

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

2、springboot启动文件中添加注解

@EnableScheduling

 3、新建Java文件  WsSessionManager.java

 1 package com.netx.edu.socket;
 2 
 3 import org.springframework.web.socket.WebSocketSession;
 4 
 5 import java.util.concurrent.ConcurrentHashMap;
 6 
 7 public class WsSessionManager {
 8 
 9     /**
10      * 保存连接 session 的地方
11      */
12     public static ConcurrentHashMap<Integer, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>();
13 
14     /**
15      * 添加 session
16      *
17      * @param key
18      */
19     public static void add(Integer key, WebSocketSession session) {
20         // 添加 session
21         SESSION_POOL.put(key, session);
22     }
23 
24     /**
25      * 删除 session,会返回删除的 session
26      *
27      * @param key
28      * @return
29      */
30     public static WebSocketSession remove(Integer key) {
31         // 删除 session
32         return SESSION_POOL.remove(key);
33     }
34 
35     /**
36      * 删除并同步关闭连接
37      *
38      * @param key
39      */
40     public static void removeAndClose(Integer key) {
41         WebSocketSession session = remove(key);
42         if (session != null) {
43             try {
44                 // 关闭连接
45                 session.close();
46             } catch (Exception  e) {
47                 e.printStackTrace();
48             }
49         }
50     }
51 
52     /**
53      * 获得 session
54      *
55      * @param key
56      * @return
57      */
58     public static WebSocketSession get(Integer key) {
59         // 获得 session
60         return SESSION_POOL.get(key);
61     }
62 
63 }
View Code

 4、新建Java文件 WsService.java

 1 package com.netx.edu.socket;
 2 
 3 import org.springframework.stereotype.Service;
 4 import org.springframework.web.socket.TextMessage;
 5 import org.springframework.web.socket.WebSocketSession;
 6 
 7 import java.io.IOException;
 8 
 9 /**
10  * ws操作相关服务
11  */
12 @Service
13 public class WsService {
14 
15     /**
16      * 发送消息
17      * @param userId
18      * @param text
19      * @return
20      * @throws IOException
21      */
22     public void sendMsg(Integer userId, String text) {
23         if(WsSessionManager.SESSION_POOL.containsKey(userId)){
24             try {
25 
26                 WsSessionManager.get(userId).sendMessage(new TextMessage(text));
27             } catch (IOException e) {
28                 e.printStackTrace();
29             }
30         }
31     }
32 
33     /**
34      * 广播消息
35      * @param text
36      * @return
37      * @throws IOException
38      */
39     public void broadcastMsg(String text) throws IOException {
40         for (WebSocketSession session: WsSessionManager.SESSION_POOL.values()) {
41             session.sendMessage(new TextMessage(text));
42         }
43     }
44 
45 }
View Code

 5、新建Java文件 MyWsHandler.java

 1 package com.netx.edu.socket;
 2 
 3 import org.slf4j.Logger;
 4 import org.slf4j.LoggerFactory;
 5 import org.springframework.stereotype.Component;
 6 import org.springframework.web.socket.BinaryMessage;
 7 import org.springframework.web.socket.CloseStatus;
 8 import org.springframework.web.socket.TextMessage;
 9 import org.springframework.web.socket.WebSocketSession;
10 import org.springframework.web.socket.handler.AbstractWebSocketHandler;
11 
12 import java.time.LocalDateTime;
13 
14 @Component
15 public class MyWsHandler extends AbstractWebSocketHandler {
16 
17     private Logger logger = LoggerFactory.getLogger(MyWsHandler.class);
18 
19     @Override
20     public void afterConnectionEstablished(WebSocketSession session) throws Exception {
21 
22         logger.info("建立ws连接");
23         Integer userId = (Integer) session.getAttributes().get("userId");
24         //WsSessionManager.add(session.getId(), session);
25         WsSessionManager.add(userId, session);
26     }
27 
28     @Override
29     protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
30         logger.info("发送文本消息");
31         // 获得客户端传来的消息
32         String payload = message.getPayload();
33         logger.info("server 接收到消息 " + payload);
34         session.sendMessage(new TextMessage("server 发送给的消息 " + payload + ",发送时间:" + LocalDateTime.now().toString()));
35     }
36 
37     @Override
38     protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
39         logger.info("发送二进制消息");
40     }
41 
42     @Override
43     public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
44         logger.error("异常处理");
45         Integer userId = (Integer) session.getAttributes().get("userId");
46         WsSessionManager.removeAndClose(userId);
47     }
48 
49     @Override
50     public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
51         logger.info("关闭ws连接");
52         Integer userId = (Integer) session.getAttributes().get("userId");
53         WsSessionManager.removeAndClose(userId);
54     }
55 
56 }
View Code

 6、新建Java文件 MyWsInterceptor.java

 1 package com.netx.edu.socket;
 2 
 3 import com.netx.edu.common.Tool;
 4 import org.springframework.http.server.ServerHttpRequest;
 5 import org.springframework.http.server.ServerHttpResponse;
 6 import org.springframework.http.server.ServletServerHttpRequest;
 7 import org.springframework.web.socket.WebSocketHandler;
 8 import org.springframework.web.socket.server.HandshakeInterceptor;
 9 
10 import java.util.Map;
11 
12 public class MyWsInterceptor implements HandshakeInterceptor {
13 
14     @Override
15     public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
16 
17         if (request instanceof ServletServerHttpRequest) {
18             ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
19             // 获取请求路径携带的参数
20             String userId = serverHttpRequest.getServletRequest().getParameter("userId");
21             Integer intUserId = Tool.parseInt(userId);
22             attributes.put("userId", intUserId);
23             return true;
24         } else {
25             return false;
26         }
27     }
28 
29     @Override
30     public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
31 
32     }
33 }
View Code

 7、新建Java文件 WebSocketConfig.java

 1 package com.netx.edu.socket;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.context.annotation.Configuration;
 5 import org.springframework.web.socket.config.annotation.EnableWebSocket;
 6 import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
 7 import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
 8 
 9 @Configuration
10 @EnableWebSocket
11 public class WebSocketConfig implements WebSocketConfigurer {
12 
13     @Autowired
14     private MyWsHandler myWsHandler;
15 
16     @Override
17     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
18 
19         registry
20 
21                 .addHandler(myWsHandler, "myWs")
22                 .addInterceptors(new MyWsInterceptor())
23                 //允许跨域
24                 .setAllowedOrigins("*");
25     }
26 }
View Code

8、新建Java广播测试类 MessageJob.java

springboot启动文件需要添加开启定时器注解

@EnableScheduling
 1 package com.netx.edu.socket;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.scheduling.annotation.Scheduled;
 5 import org.springframework.stereotype.Component;
 6 
 7 import java.io.IOException;
 8 import java.time.LocalDateTime;
 9 
10 @Component
11 public class MessageJob {
12 
13     @Autowired
14     WsService wsService;
15 
16 
17 
18     @Scheduled(cron = "0/5 * * * * *")
19     public void run() {
20         try {
21 
22             String str = "自动生成消息 " + LocalDateTime.now().toString();
23             wsService.broadcastMsg(str);
24             System.out.println(str);
25 
26         } catch (IOException e) {
27             e.printStackTrace();
28         }
29     }
30 
31 
32 }
View Code

9、新建HTML测试文件 index.html

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="utf-8"/>
 5     <title>Ionic App</title>
 6 </head>
 7 
 8 <body>
 9 <input id="text" type="text" />
10 <button onclick="send()">Send</button>
11 <button onclick="closeWebSocket()">Close</button>
12 <div id="message"></div>
13 
14 
15 </body>
16 
17 <script type="text/javascript">
18 
19     let ws = null;
20 
21     //判断当前浏览器是否支持WebSocket
22     if ('WebSocket' in window) {
23         ws = new WebSocket("ws://localhost:60314/myWs?userId=123");
24     }
25     else {
26         alert('当前浏览器 Not support websocket')
27     }
28 
29     //连接发生错误的回调方法
30     ws.onerror = function () {
31         setMessageInnerHTML("WebSocket连接发生错误");
32     };
33 
34     //连接成功建立的回调方法
35     ws.onopen = function(event) {
36         console.log("ws调用连接成功回调方法")
37         //ws.send("")
38     }
39     //接收到消息的回调方法
40     ws.onmessage = function(message) {
41         console.log("接收消息:" + message.data);
42         if (typeof(message.data) == 'string') {
43             setMessageInnerHTML(message.data);
44         }
45     }
46     //ws连接断开的回调方法
47     ws.onclose = function(e) {
48         console.log("ws连接断开")
49         //console.log(e)
50         setMessageInnerHTML("ws close");
51     }
52 
53     //将消息显示在网页上
54     function setMessageInnerHTML(innerHTML) {
55         console.log(innerHTML)
56         document.getElementById('message').innerHTML += '接收的消息:' + innerHTML + '<br/>';
57     }
58 
59     //关闭连接
60     function closeWebSocket() {
61         ws.close();
62     }
63 
64 
65     //发送消息
66     function send(msg) {
67         if(!msg){
68             msg = document.getElementById('text').value;
69             document.getElementById('message').innerHTML += "发送的消息:" + msg + '<br/>';
70             ws.send(msg);
71         }
72     }
73 </script>
74 </html>
View Code

 

 

posted on 2022-09-25 15:58  //君莫笑  阅读(41)  评论(0)    收藏  举报

导航