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 }
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 }
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 }
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 }
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 }
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 }
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>
浙公网安备 33010602011771号