zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    二分查找(通过相对位置判断区间位置)--17--二分--LeetCode33搜索旋转排序数组
    归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
    22-Java-Hibernate框架(二)
    21-Java-Hibernate框架(一)
    操作系统-5-进程管理(二)
    操作系统-4-进程管理(一)
    操作系统-3-操作系统引论
    操作系统-2-存储管理之LRU页面置换算法(LeetCode146)
    20-Java-正则表达式
    19-Java-核心类库2-包装类、Integer类、String类、StringBuffer类、StringBuilder类
  • 原文地址:https://www.cnblogs.com/cyh1282656849/p/14505633.html
Copyright © 2011-2022 走看看