• spring使用websocket(转)


    转载:https://blog.csdn.net/fffvdgjvbsfkb123456/article/details/116465394

    WebSocket介绍
    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

    WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

    协议有两部分,握手和数据传输。
    握手是基于http协议的
    来自客户端的握手形式如下:

    来自服务器的握手形式如下:

    websocket方法


    引入POM依赖

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

    WebSocket入口配置

    @Configuration  
    @EnableWebSocket  
    public class WebSocketConfig implements WebSocketConfigurer {  
        /** 
         * 注册handle 
         * @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry) 
         */  
        @Override  
        public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
              registry.addHandler(myHandler(), "/testHandler.do").addInterceptors(new WebSocketInterceptor());  
              registry.addHandler(myHandler(), "/socketJs/testHandler.do").addInterceptors(new WebSocketInterceptor()).withSockJS();  
      
        }  
          
        @Bean  
        public WebSocketHandler myHandler(){  
            return new MyMessageHandler();  
        }  
    }

    实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。
    registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理,而不实现具体的业务逻辑,可以理解为收集和任务分发中心。
    addInterceptors,是为handler添加拦截器,可以在调用handler前后加入我们自己的逻辑代码。
    创建拦截器

    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");
                attributes.put("currentUser", userId);
            }
    
            return true;
        }
    
        // 初次握手访问后
        @Override
        public void afterHandshake(ServerHttpRequest serverHttpRequest,
                ServerHttpResponse serverHttpResponse,
                WebSocketHandler webSocketHandler, Exception e) {
    
        }
    }

    beforeHandshake,在调用handler前处理方法。常用在登录用户信息,绑定WebSocketSession,在handler里根据用户信息获取WebSocketSession发送消息。

    Handler处理类

    public class MyMessageHandler implements WebSocketHandler {
    
        /**
         * userMap:使用线程安全map存储用户连接webscoket信息
         * 
         * @since JDK 1.7
         */
        private final static Map<String, WebSocketSession> userMap = new new ConcurrentHashMap<String, WebSocketSession>();
    
        /**
         * 关闭websocket时调用该方法
         * 
         * @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession,
         *      org.springframework.web.socket.CloseStatus)
         */
        @Override
        public void afterConnectionClosed(WebSocketSession session,
                CloseStatus status) throws Exception {
            String userId = this.getUserId(session);
            if (StringUtils.isNoneBlank(userId)) {
                userMap.remove(userId);
                System.err.println("该" + userId + "用户已成功关闭");
            } else {
                System.err.println("关闭时,获取用户id为空");
            }
    
        }
    
        /**
         * 建立websocket连接时调用该方法
         * 
         *  org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
         */
        @Override
        public void afterConnectionEstablished(WebSocketSession session)
                throws Exception {
            String userId = this.getUserId(session);
            if (StringUtils.isNoneBlank(userId)) {
                userMap.put(userId, session);
                session.sendMessage(new TextMessage("建立服务端连接成功!"));
            }
    
        }
    
        /**
         * 客户端调用websocket.send时候,会调用该方法,进行数据通信
         * 
         * org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession,
         *      org.springframework.web.socket.WebSocketMessage)
         */
        @Override
        public void handleMessage(WebSocketSession session,
                WebSocketMessage<?> message) throws Exception {
                String msg = message.toString();
                String userId = this.getUserId(session);
                System.err.println("该" + userId + "用户发送的消息是:" + msg);
                message = new TextMessage("服务端已经接收到消息,msg=" + msg);
                session.sendMessage(message);
        }
    
        /**
         * 传输过程出现异常时,调用该方法
         * 
         * org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession,
         *      java.lang.Throwable)
         */
        @Override
        public void handleTransportError(WebSocketSession session, Throwable e)
                throws Exception {
            WebSocketMessage<String> message = new TextMessage("异常信息:"
                    + e.getMessage());
            session.sendMessage(message);
        }
    
        /**
         * 
         *   org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
         */
        @Override
        public boolean supportsPartialMessages() {
    
            return false;
        }
    
        /**
         * sendMessageToUser:发给指定用户
         * 
         */
        public void sendMessageToUser(String userId, String contents) {
            WebSocketSession session = userMap.get(userId);
            if (session != null && session.isOpen()) {
                try {
                    TextMessage message = new TextMessage(contents);
                    session.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * sendMessageToAllUsers:发给所有的用户
         * 
         */
        public void sendMessageToAllUsers(String contents) {
            Set<String> userIds = userMap.keySet();
            for (String userId : userIds) {
                this.sendMessageToUser(userId, contents);
            }
        }
    
        /**
         * getUserId:获取用户id
         * 
         * @author liuchao
         * @param session
         * @return
         * @since JDK 1.7
         */
        private String getUserId(WebSocketSession session) {
            try {
                String userId = (String) session.getAttributes().get("currentUser");
                return userId;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    客户端连接

    <script type="text/javascript">
        $(function(){
                var host= window.location.host;
                var websocket;
                if ('WebSocket' in window) {
                    websocket = new WebSocket("ws://"+host+"/testHandler.do?userId=9528");
                } else if ('MozWebSocket' in window) {
                    websocket = new MozWebSocket("ws://"+host+"/testHandler.do?userId=9528");
                } else {
                    websocket = new SockJS("http://"+host+"/socketJs/testHandler.do?userId=9528");
                }
                websocket.onopen = function (evnt) {
                    console.log("链接服务器成功!")
                };
                websocket.onmessage = function (evnt) {
                    console.log(evnt.data);
                    $("#message").html(evnt.data);
                };
                websocket.onerror = function (evnt) {
                    console.log("websocket错误");
                };
                websocket.onclose = function (evnt) {
                    console.log("与服务器断开了链接!")
                }
                $('#send').bind('click', function() {
                    send();
                });
                function send(){
                    if (websocket != null) {
                        var message = document.getElementById('message').value;
                        websocket.send(message);
                    } else {
                        alert('未与服务器链接.');
                    }
                }
        });
    </script>
  • 相关阅读:
    Installing Python Modules
    《利用Python 进行数据分析》
    使用Python进行描述性统计
    各种数字证书区别
    数字证书及CA的扫盲介绍
    expect学习笔记及实例详解
    使用openssl命令制作ecc证书
    那些证书相关的玩意儿(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等)
    Openssl与私有CA搭建
    Openssl编程--源码分析
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16648965.html
Copyright © 2020-2023  润新知