• spring中使用websocket(二)


    日常情况下,无状态的http请求已经足够满足大部分CS直接的交互。

    但有些特殊情况下,客户端和服务端需要维护长链接,互相获取对方的连接状态,这个时候就需要用到websocket。

    在spring中使用websocket还是比较简单的,首先引入依赖jar包

     <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-websocket</artifactId>
                <version>4.2.4.RELEASE</version>
            </dependency>

    然后定义一个websocket配置类,将URL、消息处理类和拦截器进行注册

    拦截器一般用户在链接建立初期初始化一些内容,比如用户信息、项目信息等等。

    消息处理器一般用于处理核心逻辑的地方,需要和客户端约定消息格式和消息类型,客户端发送什么消息,服务端回复哪些消息。

    @Configuration
    @EnableWebSocket
    public class WebSocketConfig implements WebSocketConfigurer {
        @Override
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
            //允许跨域
    registry.addHandler(yourHandler(),"/url").addInterceptors(yourInterceptor()).setAllowedOrigins("*");
        }
    
        @Bean
        public WebSocketHandler yourHandler() {
            return new MessageHandler();
        }
    
        @Bean
        public WebSocketInterceptor yourInterceptor(){
            return  new WebSocketInterceptor();
        }
    }

    下面是拦截器的实现

    @Slf4j
    public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest request,
                                       ServerHttpResponse response, WebSocketHandler wsHandler,
                                       Map<String, Object> attributes) throws Exception {
            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
                // 获取参数
                String userId = serverHttpRequest.getServletRequest().getParameter(
                        "userId");
                
                log.info("连接建立了!userId="+userId);
                log.info(path);
            }
    
            return true;
        }
    
        // 初次握手访问后
        @Override
        public void afterHandshake(ServerHttpRequest serverHttpRequest,
                                   ServerHttpResponse serverHttpResponse,
                                   WebSocketHandler webSocketHandler, Exception e) {
    
        }
    
    }

    接下来就是消息处理器的实现

    @Slf4j
    @Service
    public class MessageHandler implements WebSocketHandler {
    
        
    
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
           
            log.info("建立服务端连接成功!");
        }
    
        @Override
        public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> message) throws Exception {
            String payload = message.getPayload().toString();
            log.info("收到消息:"+payload);
            webSocketSession.sendMessage(new TextMessage("你好,这是是服务端!"));
    
    
        }
    
        @Override
        public void handleTransportError(WebSocketSession webSocketSession, Throwable e) throws Exception {
    
            log.error(e.getMessage());
        }
    
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
            userMap.remove(session.getId());
            log.info("连接关闭了!");
    
        }
    
        @Override
        public boolean supportsPartialMessages() {
            return false;
        }
    
       
    }

    还有最最重要一点,代码写完了,怎么测试啊?

    没问题,我们自己写了一个简陋的前端代码,测试下连接还是没问题的。

    <!DOCTYPE HTML>
    <html>
    <head>
        <meta charset="utf-8">
        <title>websocket</title>
        <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript">
             function WebSocketTest()
             {
                if ("WebSocket" in window)
                {
                   alert("您的浏览器支持 WebSocket!");
    
                  var ws = new WebSocket("ws://localhost:8080/yoururl?userId=99");
                    alert("建立连接...");
                   ws.onopen = function()
                   {
                   alert("数据发送中...");
                      ws.send("发送数据");
                   };
                    ws.onclose= function (evnt) {
                    alert("与服务器断开了链接!")
                };
    
                ws.onmessage = function (evt) 
                   { 
                      var received_msg = evt.data;
                      alert("数据已接收...");
                      alert(received_msg );
                   };
    
                ws.onerror = function (evnt) {
                    alert("websocket错误");
                };
                $(document).ready(function(){
      $("button").click(function(){
        alert("按钮被点击了");
        if (ws != null) {
                        var message = "hello,ws";
                        ws.send(message);
                    } else {
                        alert('未与服务器链接.');
                    }
                    });
      });
    }
                
                else
                {
                   // 浏览器不支持 WebSocket
                   alert("您的浏览器不支持 WebSocket!");
                }
             }
        </script>
    
    </head>
    <body>
    
    <div id="sse">
        <a href="javascript:WebSocketTest()">运行WebSocket</a>
        <button>发送消息</button>
    </div>
    
    </body>
    </html>

    下面就可以愉快的测试了。

  • 相关阅读:
    求所有科目都大于80分的学生姓名
    sql server如何设置密码过期时间呢?
    sql server官网使用查找技术文档(msdn、联机丛书)
    【版本特性】sql server2014版本特性
    SQLSERVER文件组误脱机后如何联机
    sql server2014中的内存优化表/内存表(续写)
    JNI日志调试LOG和中文乱码
    JNI常见错误整理
    什么是“软解码”,什么又是“硬解码”呢?
    创建eclipse针对NDK的联合编译环境。
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16668665.html
Copyright © 2020-2023  润新知