美文网首页
springboot整合websocket,解决session不

springboot整合websocket,解决session不

作者: 飘_摇_ | 来源:发表于2020-05-26 15:42 被阅读0次

    需求:页面每分钟获取最新告警。
    问题:最开始前端使用定时器每一分钟去服务端取告警,这样导致session永远不会超时。
    解决:使用websocket协议来推送告警。
    pom中增加:

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

    增加配置类,使用ServerEndpoint创建websocket endpoint

    @Configuration
    public class WebSocketConfig {
    
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    后端具体实现类

    @ServerEndpoint("/alarm")
    @Component
    @Slf4j
    public class AlarmSocket {
    
        @Autowired
        IndexService indexService;
    
        /**
         * 用于存放所有在线客户端
         */
        private static Map<String, Session> clients = new ConcurrentHashMap<>();
    
        @OnOpen
        public void onOpen(Session session) {
            log.info("有新的客户端上线: {}", session.getId());
            clients.put(session.getId(), session);
        }
    
        @OnClose
        public void onClose(Session session) {
            String sessionId = session.getId();
            log.info("有客户端离线: {}", sessionId);
            clients.remove(sessionId);
        }
    
        @OnError
        public void onError(Session session, Throwable throwable) {
            String sessionId = session.getId();
            if (clients.get(sessionId) != null) {
                log.info("发生了错误,移除客户端: {}", sessionId);
                clients.remove(sessionId);
            }
            throwable.printStackTrace();
        }
    
        @OnMessage
        public void onMessage(String message, Session session) {
            log.info("收到客户端发来的消息: {}", message);
        }
    
        /**
         * 每一分钟群发一次告警消息
         */
        @Scheduled(cron="0 0/1 * * * ?")
        private void sendAll() {
            String msg=JSON.toJSONString(R.ok(indexService.getTopAlarm()));
            for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
                try {
                    sessionEntry.getValue().getAsyncRemote().sendText(msg);
                }catch (Exception e){
                    log.error("发送告警消息失败,删除session"+sessionEntry.getValue());
                    try {
                        clients.remove(sessionEntry.getKey());
                    }catch (Exception e1){
                        log.error("根据sessionId删除失败,清除sessionMap");
                        clients.clear();
                    }
                }
            }
        }
    
    }
    

    前端代码

    function startSocket() {
            let url='ws://localhost:8088/monitor/alarm';
            //用于告警定时刷新,解决session不超时问题
            var webSocket = null;
            if ('WebSocket' in window) {
                webSocket = new WebSocket(url);
            }
            else {
                alert('Not support websocket')
            }
            webSocket.onerror = function (event) {
                onError(event)
            };
    
            webSocket.onopen = function (event) {
                onOpen(event)
            };
    
            webSocket.onmessage = function (event) {
                onMessage(event)
            };
    
            function onMessage(event) {
                var res = eval('(' + event.data + ')');
                console.log(res);
            }
    
            function onOpen(event) {
                console.log('Connection established');
                start();
            }
    
            function onError(event) {
                console.log('socket error==='+event.data);
            }
    
            function start() {
                webSocket.send('你好');
                return false;
            }
        }
    

    相关文章

      网友评论

          本文标题:springboot整合websocket,解决session不

          本文链接:https://www.haomeiwen.com/subject/qtkbohtx.html