美文网首页
WebSocket和sharedWork简介

WebSocket和sharedWork简介

作者: 柳岸花开 | 来源:发表于2017-09-26 10:17 被阅读114次

注意事项:
1.如果出现握手失败,检查路径之外还可以去查看拦截器是否做了什么处理

WebSocket是持久化连接,用于解决浏览器与后台服务器双向通讯的问题
sharedWorker共享工作线程允许多个页面共享使用,每个页面都是链接到该共享工作线程的某个端口号上。页面通过该端口与共享工作线程进行通信

配置所需jar包

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>${spring.framework.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>${spring.framework.version}</version>
</dependency>

这里所用的版本最好和项目中所用到的spring其他内容统一,避免出现版本不兼容问题。
对版本的要求是:spring版本为 4.0 版本及以上, Tomcat 7.047 以上版本。

websocket入口

/**
 * Component注解告诉SpringMVC该类是一个SpringIOC容器下管理的类
 * 其实@Controller, @Service, @Repository是@Component的细化
 * @Configuration注解该类,等价于XML中配置beans标签
 */
@Configuration
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //一般浏览器都会支持
        registry.addHandler(WebSocketPushHandler(),"/webSocketServer").addInterceptors(new MyHandShakeInterceptor());
        //低版本浏览器使用此路径,等下页面上会讲到
        registry.addHandler(WebSocketPushHandler(), "/sockjs/webSocketServer").addInterceptors(new MyHandShakeInterceptor())
                .withSockJS();
    }
    @Bean
    public WebSocketHandler WebSocketPushHandler(){
        return new MyWebSocketHander();
    }
}
  • 实现WebSocketConfigurer接口,重写registerWebSocketHandlers方法,这是一个核心实现方法,配置websocket入口,允许访问的域、注册Handler、SockJs支持和拦截器。

  • registry.addHandler注册和路由的功能,当客户端发起websocket连接,把/path交给对应的handler处理, 而不实现具体的业务逻辑,可以理解为收集和任务分发中心。

  • setAllowedOrigins(String[] domains),允许指定的域名或IP(含端口号)建立长连接,如果只允许自家域名访问,这里轻松设置。 如果不限时使用”*”号,如果指定了域名,则必须要以http或https开头。

  • 拦截器实现

    /**
     * websocket握手拦截器
     * 拦截握手前,握手后的两个切面
     */
    public class MyHandShakeInterceptor implements HandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                       Map<String, Object> attributes) throws Exception {
            System.out.println("准备进行握手");
            if (request instanceof ServletServerHttpRequest) {
    //            attributes.put("username",userName);
            }
            return true;
        }
        @Override
        public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                                   Exception exception) {
            System.out.println("握手成功,进入服务端");
        }
    }

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

    Handler处理类

    /**WebSocket处理器
     * Created by qiumeng on 2017/8/7 0007.
     */
    public class MyWebSocketHander extends TextWebSocketHandler {
    
    
        private static final List<WebSocketSession> users = new ArrayList<>();
    
    
        //用户进入系统监听
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            System.out.println("成功进入了系统。。。");
            users.add(session);
        }
        @Override
        public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
            System.out.println("成功接收到消息");
            // 把客户端的消息解析为JSON对象
            if(message instanceof TextMessage) {
    
    
                TextMessage msg = new TextMessage("发送的数据"+message.getPayload());
                //给所有浏览器群发消息
                sendMessagesToUsers(msg);
    //            this.handleTextMessage(session, (TextMessage)message);
            } else if(message instanceof BinaryMessage) {
                BinaryMessage msg = new BinaryMessage((byte[]) message.getPayload());
                //给所有浏览器群发消息
                sendMessagesToUsers(msg);
    //            this.handleBinaryMessage(session, (BinaryMessage)message);
            } else {
                if(!(message instanceof PongMessage)) {
                    throw new IllegalStateException("Unexpected WebSocket message type: " + message);
                }
    //            this.handlePongMessage(session, (PongMessage)message);
            }
    
    
        }
    
    
        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {}
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {System.out.println("安全退出了系统");}
        @Override
        public boolean supportsPartialMessages() {
            return false;
        }
        /**
         * 给所有的用户发送消息
         */
        public void sendMessagesToUsers(WebSocketMessage<?>  message){
            for(WebSocketSession user : users){
                try {
                    //isOpen()在线就发送
                    if(user.isOpen()){
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //进行实例化bean可以在其他controller实例化 调用所发送的信息
        @Bean
        public MyWebSocketHander myWebSocketHander(){
            return myWebSocketHander();
        }
    }

    客户端连接

    这里只写出javascript代码

    这是websocket.js代码

    <script type="text/javascript">
        var receive_text = document.getElementById("up");
    	//这是websocket访问后台
        var myWorker = new SharedWorker('http://localhost:8081/portal/resources/js/worker.js');
        console.log("创建sharedwork");
    
    
        myWorker.onerror = function(e)
        {
            console.log('myWorker.onerror : ' + e.message);
        }
        function myOnMessage(e) {
            receive_text.innerHTML += "<br/>" + e.data;
            receive_text.scrollTop = receive_text.scrollHeight;
    
    
        }
        if(1){
            // 4 绑定消息处理函数,仅设置 onmessage
            myWorker.port.onmessage = myOnMessage;
        }
        else{
            // 5 另外一种消息绑定方式, addEventListener 和 start 配合使用
            myWorker.port.addEventListener('message', myOnMessage);
            myWorker.port.start();
        }
    
    
        function send(){
            var ret = myWorker.port.postMessage(JSON.stringify($("#message").val()))
        }
        //页面发送消息
        function sendMessage() {
    
    
    //        var ret = myWorker.port.postMessage(stringToBytes($("#message").val()))
            var file=$("#file")[0].files[0];
            var reader = new FileReader();
            if(""==file){
                alert("请选择文件")
            }
    //        reader.readAsBinaryString(file)
            reader.readAsArrayBuffer(file)
            reader.onload = function (e) {
                if (e.target.readyState == FileReader.DONE) {
                    var data = new Uint8Array(e.target.result);
                    //这里有一个问题,目前没有解决 就是传输二进制数据大小的问题 好像为100万字节左右 
                    //在大的话,目前没有找到解决办法
                    var jsondata=JSON.stringify(data.slice(0, 100))
                    var ret = myWorker.port.postMessage(jsondata);
                }
            }
    
    
        }
    </script>
    
    
    下面是创建sharedWorker主线程代码work.js
    var count = 0;
    var ports = [];
    var webSocket = new WebSocket("ws://localhost:8081/portal/webSocketServer");
    var websocketMessage=null;
    
    
    // 唯一的事件处理函数
    onconnect = function(e) { 
    console.log('onconnect from home');
    // 1 网页建立连接获取端口
    var port = e.ports[0];
    
    ports.push({
    port:port,
    lastRecv: new Date()
    });
    
    
    // 2 绑定事件处理函数
    port.addEventListener('message', function(e) {
    var ret = e.data;
            //因为WebSockets只能通过连接发送纯文本数据,所以对于复杂的数据结构,在通过连接发送之前,必须进行序列化
    //发送消息到后台
    if(""!=ret){
                console.log("向websocket后台发送消息")
    webSocket.send(ret);
    }
    });
    // 3 启动端口
    port.start();
    }
    
    
    webSocket.onopen = function(event) {
        console.log("websocket创建");
    };
    
    
    webSocket.onmessage = function(event) {
        console.log("websocket返回消息")
        websocketMessage=event.data
        //data的数据格式也是字符串,如果想得到其他格式的数据,必须手工解析这些数据
        for(var i=0;i<ports.length;i++){
            var p=ports[i];
            p.port.postMessage(websocketMessage)
        }
    };
    webSocket.onerror = function(event) {
    
    
    };

    相关文章

    • WebSocket和sharedWork简介

      注意事项: 1.如果出现握手失败,检查路径之外还可以去查看拦截器是否做了什么处理 WebSocket是持久化连接,...

    • websocket使用

      websocket简介 websocket:github参考 实例:vue+websocket在线聊天室 浏览器和...

    • 好程序员web前端培训分享WebSocket协议

      好程序员web前端培训分享WebSocket协议,WebSocket协议简介 一.WebSocket协议简介 1....

    • websocket整理

      简介 websocket简介 HTML5 WebSocket设计出来的目的就是取代轮询和长连接,使客户端浏览器具备...

    • 遇到Websocket就不会测了?别慌,学会这个Jmeter插件

      01websocket简介及优势 1.websocket简介: websocket 是一种双向通信协议,在建立连接...

    • 基于Node.js的WebSocket通信

      Websocket简介[维基百科] WebSocket is a computer communications ...

    • Websocket

      参考资料 Websocket简介 Websocket API Websocket 阮一峰 nodejs建立webs...

    • websocket学习

      WebSocket简介 谈到Web实时推送,就不得不说WebSocket。在WebSocket出现之前,很多网站为...

    • websocket简介

      一、websocket与http WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或...

    • WebSocket简介

      作为下一代的 Web 标准,HTML5 拥有许多引人注目的新特性,如 Canvas、本地存储、多媒体编程接口、We...

    网友评论

        本文标题:WebSocket和sharedWork简介

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