spring boot Websocket
-
pom 依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
-
注册websocket服务
/** * @ClassName WebSocketConfig * @Description TODO * @Author gm * @Date 2021/1/3 16:02 */ @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { //websocket事件处理(连接的建立和断开、客户端消息接收) @Autowired private HttpAuthHandler httpAuthHandler; //握手拦截器 @Autowired private MyInterceptor myInterceptor; @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry .addHandler(httpAuthHandler, "myWS") .addInterceptors(myInterceptor) .setAllowedOrigins("*"); System.out.println(" websocket-register-succes"); } }
-
websocket事件处理handler
/** * 处理websocket事件 * * @ClassName EchoWebSocketHandler * @Description TODO * @Author gm * @Date 2021/1/3 16:18 */ @Component public class HttpAuthHandler extends TextWebSocketHandler { /** * socket 建立成功事件 * * @param session * @throws Exception */ @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // Object token = session.getAttributes().get("token"); // if (token != null) { // // 用户连接成功,放入在线用户缓存 // WsSessionManager.add(token.toString(), session); // } else { // throw new RuntimeException("用户登录已经失效!"); // } //展示使用id 回头做了token换上 Object token = session.getId(); System.out.println("token = " + token); if (token != null) { // 用户连接成功,放入在线用户缓存 WsSessionManager.add(token.toString(), session); } else { throw new RuntimeException("用户登录已经失效!"); } } /** * 接收消息事件 * * @param session * @param message * @throws Exception */ @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 获得客户端传来的消息 String payload = message.getPayload(); Object token = session.getAttributes().get("token"); System.out.println("server 接收到 " + token + " 发送的 " + payload); session.sendMessage(new TextMessage("server 发送给 " + token + " 消息 " + payload + " " + LocalDateTime.now().toString())); } /** * socket 断开连接时 * * @param session * @param status * @throws Exception */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { Object token = session.getAttributes().get("token"); if (token != null) { // 用户退出,移除缓存 WsSessionManager.remove(token.toString()); } } }
-
握手拦截器
/** * 握手拦截器 * * @ClassName MyInterceptor * @Description TODO * @Author gm * @Date 2021/1/3 16:29 */ @Component public class MyInterceptor implements HandshakeInterceptor { /** * 握手前 * * @param request * @param response * @param wsHandler * @param attributes * @return * @throws Exception */ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { System.out.println("握手开始"); return true; } /** * 握手后 * * @param request * @param response * @param wsHandler * @param exception */ @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { System.out.println("握手完成"); } }
-
连接session的管理
/** * 管理session * * @ClassName WsSessionManager * @Description TODO * @Author gm * @Date 2021/1/3 16:27 */ @Slf4j public class WsSessionManager { /** * 保存连接 session 的地方 */ private static ConcurrentHashMap<String, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>(); /** * 添加 session * * @param key */ public static void add(String key, WebSocketSession session) { // 添加 session SESSION_POOL.put(key, session); } /** * 删除 session,会返回删除的 session * * @param key * @return */ public static WebSocketSession remove(String key) { // 删除 session return SESSION_POOL.remove(key); } /** * 删除并同步关闭连接 * * @param key */ public static void removeAndClose(String key) { WebSocketSession session = remove(key); if (session != null) { try { // 关闭连接 session.close(); } catch (IOException e) { // todo: 关闭出现异常处理 e.printStackTrace(); } } } /** * 获得 session * * @param key * @return */ public static WebSocketSession get(String key) { // 获得 session return SESSION_POOL.get(key); } }
-
对应前端vue
<template> <div style="text-align: center"> <van-nav-bar title="websocket相关" left-text="返回" left-arrow @click-left="navClickLeft" > </van-nav-bar> <van-row> <van-col span="24"> <van-button type="primary" @click="send">发送</van-button> <van-button type="primary" @click="closeSession">关闭会话</van-button> </van-col> </van-row> <van-row> <van-field v-model="sendMessage" name="发送消息" label="发送消息" placeholder="发送消息" /> </van-row> <van-row> <van-field v-model="getMessage" name="收到的消息" label="收到的消息" placeholder="收到的消息" /> </van-row> </div> </template> <script scoped> import config from "@/global/config"; export default { name: "websocket", props: {}, components: {}, computed: {}, data() { return { homePath: '/demo/home', websocket: {}, testWebsocketUrl: 'ws://'+config.SERVER_HOST+'/myWS', sendMessage: '', getMessage: '' } }, methods: { navClickLeft() { this.$router.push(this.homePath) }, send() { this.websocket.send(this.sendMessage); }, closeSession() { this.websocket.close(); }, initWebsocket() { let self = this; //判断当前浏览器是否支持WebSocket, 主要此处要更换为自己的地址 if ('WebSocket' in window) { this.websocket = new WebSocket(this.testWebsocketUrl); } else { alert('Not support websocket') } //连接发生错误的回调方法 this.websocket.onerror = () => { self.setMessage("error"); }; //连接成功建立的回调方法 this.websocket.onopen = (event) => { } //接收到消息的回调方法 this.websocket.onmessage = (event) => { self.setMessage(event.data); } //连接关闭的回调方法 this.websocket.onclose = () => { self.setMessage("close"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = () => { self.websocket.close(); } }, setMessage(message) { this.getMessage = message; this.$dialog.confirm({ message: message, theme: 'round-button', }).then(() => { }); } }, mounted() { }, created() { this.initWebsocket(); } } </script> <style scoped> </style>