精华内容
下载资源
问答
  • var userId = $("#userId").val(); var lockReconnect = false;... //判断当前浏览器是否支持WebSocket var wsUrl = serverConfig.cyberhouse_ws+userId; createWebSocket(wsUrl); //连接ws function ...
    var userId = $("#userId").val();
    var lockReconnect = false; //避免ws重复连接
    var ws = null; //判断当前浏览器是否支持WebSocket
    var wsUrl = serverConfig.cyberhouse_ws+userId;
    createWebSocket(wsUrl);   //连接ws
    
    function createWebSocket(url) {
        try {
            if ('WebSocket' in window) {
                ws = new WebSocket(url);
            } else if ('MozWebSocket' in window) {
                ws = new MozWebSocket(url);
            } else {
                layui.use(['layer'], function() {
                    var layer = layui.layer;
                    layer.alert("您的浏览器不支持websocket的协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!");
                });
            }
            initEventHandle();
        } catch(e) {
            reconnect(url);
            console.log(e);
        }
    }
    
    function initEventHandle() {
        ws.onclose = function() {
            reconnect(wsUrl);
            console.log("llws连接关闭!"+new Data().toUTCString());
        };
        ws.onerror = function() {
            reconnect(wsUrl);
            console.log("llws连接错误!");
        };
        ws.onopen = function() {
            heartCheck.reset().start(); //心跳检测重置
            console.log("llws连接成功!"+new Data().toUTCString());
        };
        ws.onmessage = function(event) {//如果获得到消息、心跳检测重置
            heartCheck.reset().start();    //拿到任何消息都说明当前连接是正常的
            console.log("llws收到消息啦:"+event.data);
            if (event.data != 'pong') {
                var obj = eval("("+event.data+")");
                layui.use(['layim'], function(layim) {
                    if (obj.type == "onlineStatus") {
                        layim.setFriendStatus(obj.id, obj.content);
                    } else if (obj.type == "friend" || obj.type == "group") {
                        layim.getMessage(obj);
                    }
                });
            }
        };
    }
    
    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server断会抛异常
    window.onbeforeunload = function() {
        ws.close();
    }
    
    function reconnect(url) {
        if (lockReconnect) return;
        lockReconnect = true;
        setTimeout(function() { //没连接上会一直重连,设置延迟避免请求过多
            createWebSocket(url);
            lockReconnect = false;
        }, 2000);
    }
    
    //心跳检测
    var heartCheck = {
        timeout: 540000,   //9分钟发一次心跳
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function() {
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function() {
            var self = this;
            this.timeoutObj = setTimeout(function() {
                //这里发送一个心跳,后端收到后,返回一个心跳消息,
                //onmessage拿到返回的心跳就说明连接正常
                ws.send("ping");
                console.log("ping!");
                self.serverTimeoutObj = setTimeout(function() {//如果超过一定时间还没重置,说明后端主动断开了
                    ws.close(); //如果onclose会执行reconnect,我们执行ws.close()就行了,如果直接执行reconnect会触发onclose导致重连两次
                }, self.timeout)
            }, this.timeout)
        }
    }
    
    //收到客户端消息后调用的方法
    @OnMessage
    public void onMessage(String message, Session session) {
        if (message.equals("ping")) {
        } else {
        ...
        }
    }
    

    系统发现websocket每隔10分钟自动断开连接,搜了很多博客都说设置一下nignx的

    keepalive_timeout

    proxy_send_timeout

    proxy_connect_timeout

    proxy_read_timeout

    这四个字段的时长即可,然而好像并不生效。遂采取心跳包的方式每隔9分钟客户端自动发送ping消息给服务端,服务端不需要返回。即可解决问题。

    转自:https://blog.csdn.net/jkxqj/article/details/77848466

    展开全文
  • 近日,在公司中开发一个使用websocket为前端推送消息的功能时,发现一个问题:就是每隔一段时间如果不传送数据的话,与前段的连接就会自动断开; 刚开始以为是session的原因,因为web session 的默认时间是30分钟;...

    近日,在公司中开发一个使用websocket为前端推送消息的功能时,发现一个问题:就是每隔一段时间如果不传送数据的话,与前段的连接就会自动断开;

    刚开始以为是session的原因,因为web session 的默认时间是30分钟;但是通过日志发现断开时间间隔时间远远不到30分钟;认真分析发现不操作间隔恰好为90秒

    它就会在自动断开;随恍然大悟;原来是我们的使用nginx 代理,nginx配置了访问超时时间为90s;

    WebSocket是html5中用来实现长连接的一个协议。
    在同时使用nginx反向代理和websocket的时候,因为websocket的通信管道必须都要一直处于开启状态。

    proxy_read_timeout 90;
    

    解决方案:

    1. 修改nginx配置
    nginx 通过在客户端和后端服务器之间建立起一条隧道来支持WebSocket。
    为了使nginx可以将来自客户端的Upgrade请求发送给后端服务器,Upgrade和Connection的头信息必须被显式的设置。如下所示:

    location /web/count {
            proxy_pass http://tomcat-server;
            proxy_redirect off;
            proxy_http_version 1.1;
    
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    }
    

    一旦我们完成以上设置,nginx就可以处理WebSocket连接了。
    注意,必须要有

    proxy_set_header Host $host:$server_port;   
    

    这个配置
    否则,会报:
    WebSocket connection to 'ws://192.168.1.104:9080/web/count' failed: Error during WebSocket handshake: Unexpected response code: 403的错误

    2. 也可以在前端页面也添加心跳机制保持连接。

    var userId=$("#userId").val();
    var lockReconnect = false;  //避免ws重复连接
    var ws = null;          // 判断当前浏览器是否支持WebSocket
    var wsUrl = serverConfig.cyberhouse_ws+userId;
    createWebSocket(wsUrl);   //连接ws
    
    function createWebSocket(url) {
        try{
            if('WebSocket' in window){
                ws = new WebSocket(url);
            }else if('MozWebSocket' in window){  
                ws = new MozWebSocket(url);
            }else{
                layui.use(['layer'],function(){
                  var layer = layui.layer;
                  layer.alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!"); 
                });
            }
            initEventHandle();
        }catch(e){
            reconnect(url);
            console.log(e);
        }     
    }
    
    function initEventHandle() {
        ws.onclose = function () {
            reconnect(wsUrl);
            console.log("llws连接关闭!"+new Date().toUTCString());
        };
        ws.onerror = function () {
            reconnect(wsUrl);
            console.log("llws连接错误!");
        };
        ws.onopen = function () {
            heartCheck.reset().start();      //心跳检测重置
            console.log("llws连接成功!"+new Date().toUTCString());
        };
        ws.onmessage = function (event) {    //如果获取到消息,心跳检测重置
            heartCheck.reset().start();      //拿到任何消息都说明当前连接是正常的
            console.log("llws收到消息啦:" +event.data);
            if(event.data!='pong'){
                var obj=eval("("+event.data+")");
                layui.use(['layim'], function(layim){
                    if(obj.type=="onlineStatus"){
                        layim.setFriendStatus(obj.id, obj.content);
                    }else if(obj.type=="friend" || obj.type=="group"){
                        layim.getMessage(obj);  
                    } 
        };
    }
    // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function() {
        ws.close();
    }  
    
    function reconnect(url) {
        if(lockReconnect) return;
        lockReconnect = true;
        setTimeout(function () {     //没连接上会一直重连,设置延迟避免请求过多
            createWebSocket(url);
            lockReconnect = false;
        }, 2000);
    }
    
    //心跳检测
    var heartCheck = {
        timeout: 540000,        //9分钟发一次心跳
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(function(){
                //这里发送一个心跳,后端收到后,返回一个心跳消息,
                //onmessage拿到返回的心跳就说明连接正常
                ws.send("ping");
                console.log("ping!")
                self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了
                    ws.close();     //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                }, self.timeout)
            }, this.timeout)
        }
    }
    
    // 收到客户端消息后调用的方法 
        @OnMessage  
        public void onMessage(String message, Session session) {  
            if(message.equals("ping")){
            }else{
            。。。。
            }
       }
    

    系统发现websocket每隔10分钟自动断开连接,搜了很多博客都说设置一下nginx的
    keepalive_timeout
    proxy_connect_timeout
    proxy_send_timeout
    proxy_read_timeout
    这四个字段的时长即可,然而好像并不奏效。遂采取心跳包的方式每隔9分钟客户端自动发送ping消息给服务端,服务端不需要返回。即可解决问题。

    展开全文
  • 工作当中所遇到的问题以及解决方式 起初本人的设计方式为: 前后端两端进行websocket通信 ...前端加入心跳包机制 后端接收心跳包之后不进行任何消息的接收 直接附上代码: 注:此代码为提供思路代码 <scri...

    工作当中所遇到的问题以及解决方式

    起初本人的设计方式为:

    前后端两端进行websocket通信
    1:前端基础的连接以及消息发送和接收
    2:后端基础的消息接收和发送

    过程中问题暴露:

    建立连接之后,10分钟内没有消息间的通信;websocket会自动断开连接

    解决方式:

    前端加入心跳包机制

    后端接收心跳包之后不进行任何消息的接收

    直接附上代码:
    注:此代码为提供思路代码

    <script>
    export default {
        data() {
            return {
                websock: null,//建立的连接
                lockReconnect: false,//是否真正建立连接
                timeout: 28*1000,//30秒一次心跳
                timeoutObj: null,//心跳心跳倒计时
                serverTimeoutObj: null,//心跳倒计时
                timeoutnum: null,//断开 重连倒计时
            };
        },
        created() {
            //页面刚进入时开启长连接
            this.initWebSocket();
        },
        destroyed: function() {
            //页面销毁时关闭长连接
            this.websocketclose();
        },
        methods: {
            initWebSocket(){//建立连接
                //初始化weosocket
                //const wsuri = "ws://sms.填写您的地址.com/websocket/" + this.charId; //ws地址
               const wsuri = "" 
               //建立连接
                this.websock = new WebSocket(wsuri);
                //连接成功
                this.websock.onopen = this.websocketonopen;
                //连接错误
                this.websock.onerror = this.websocketonerror;
                //接收信息
                this.websock.onmessage = this.websocketonmessage;
                //连接关闭
                this.websock.onclose = this.websocketclose;
            },
            reconnect() {//重新连接
                var that = this;
                if(that.lockReconnect) {
                    return;
                };
                that.lockReconnect = true;
                //没连接上会一直重连,设置延迟避免请求过多
                that.timeoutnum && clearTimeout(that.timeoutnum);
                that.timeoutnum = setTimeout(function () {
                    //新连接
                    that.initWebSocket();
                    that.lockReconnect = false;
                },5000);
            },
            reset(){//重置心跳
                var that = this;
                //清除时间
                clearTimeout(that.timeoutObj);
                clearTimeout(that.serverTimeoutObj);
                //重启心跳
                that.start();
            },
            start(){//开启心跳
                var self = this;
                self.timeoutObj && clearTimeout(self.timeoutObj);
                self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
                self.timeoutObj = setTimeout(function(){
                    //这里发送一个心跳,后端收到后,返回一个心跳消息,
                    if (self.websock.readyState == 1) {//如果连接正常
                        self.websock.send("heartCheck");
                    }else{//否则重连
                        self.reconnect();
                    }
                    self.serverTimeoutObj = setTimeout(function() {
                        //超时关闭
                        self.websock.close();
                    }, self.timeout);
    
                }, self.timeout)
            },
            
            websocketonopen() {//连接成功事件
              
                //提示成功
                s.success("连接成功",3)
                //开启心跳
                this.start();
            },
            
            websocketonerror(e) {//连接失败事件
                //错误
                console.log("WebSocket连接发生错误");
                //错误提示
                s.error("Websocket error, Check you internet!")
                //重连
                this.reconnect();
            },
            websocketclose(e) {//连接关闭事件
                //关闭
                console.log("connection closed (" + e.code + ")");
                //提示关闭
                s.error("连接已关闭",3);
                //重连
                this.reconnect();
            },
            websocketonmessage(event) {//接收服务器推送的信息
                //打印收到服务器的内容
                console.log(event.data);
                //收到服务器信息,心跳重置
                this.reset();
            },
            websocketsend(msg) {//向服务器发送信息
                //数据发送
                this.websock.send(msg);
            },
        }
    };
    
    </script>
    
    展开全文
  • websocket心跳

    2019-07-10 13:45:41
    websocket心跳,包括心跳代码、前台代码、后台代码
  • 20 },21 //打开websocket 22 wsOpen: function(e) {23 //开始websocket心跳 24 wsConnection.startWsHeartbeat();25 console.log('ws success')26 },27 wsClose: function(e) {28 console.log(e, 'ws close')29 },30...

    这套代码可以拿过去直接用 一些注意我会在下面代码中加上注释:

    谢谢支持

    核心代码

    1 //这里需要引入vuex

    2 import store from './store';3

    4 let wsConnection ={5 $ws: null,6 lockReturn: false,7 timeout: 60 * 1000 * 5,8 timeoutObj: null,9 timeoutNum: null,10 serverTimeoutObj: null,11 //初始化webSocket长连接

    12 initWebSocket: function() {15

    this.$ws = new WebSocket(wsurl);//写入地址 这里的地址可以在initWebSocket方法加入参数

    16 this.$ws.onopen = this.wsOpen;17 this.$ws.onclose = this.wsClose;18 this.$ws.onmessage = this.wsMsg;19 this.$ws.onerror = this.wsError;20 },21 //打开websocket

    22 wsOpen: function(e) {23 //开始websocket心跳

    24 wsConnection.startWsHeartbeat();25 console.log('ws success')26 },27 wsClose: function(e) {28 console.log(e, 'ws close')29 },30 wsMsg: function(msg) {31 //每次接收到服务端消息后 重置websocket心跳

    32 wsConnection.resetHeartbeat();33 //服务端发送来的消息存到vuex

    34 store.commit('web_socket_msg', msg)35 },36 wsError: function(err) {37 console.log(err, 'ws error');38 wsConnection.reconnect()39 },40 //重启websocket

    41 reconnect: function() {42 let _this = this;43 if(_this.lockReturn) {44 return;45 }46 _this.lockReturn = true;47 _this.timeoutNum &&clearTimeout(_this.timeoutNum);48 _this.timeoutNum = setTimeout(function() {49 _this.initWebSocket();50 _this.lockReturn = false;51 }, 3000);52 },53 startWsHeartbeat: function() {54 let _this = this;55 _this.timeoutObj &&clearTimeout(_this.timeoutObj);56 _this.serverTimeoutObj &&clearTimeout(_this.serverTimeoutObj);57 _this.timeoutObj = setInterval(function() {58 //判断websocket当前状态

    59 if (_this.$ws.readyState != 1) {60 _this.reconnect()61 }62 }, _this.timeout);63 },64 //重置websocket心跳

    65 resetHeartbeat: function() {66 let _this = this;67 clearTimeout(_this.timeoutObj);68 clearTimeout(_this.serverTimeoutObj);69 _this.startWsHeartbeat()70 }71 };72

    73 //抛出websocket对象

    74 export default wsConnection

    websocket方法调用

    1 //在main.js引入

    2 import wsConnection from './vuex/wsStore'

    3 //挂载vue原型链

    4 Vue.prototype.$setWs =wsConnection;5

    6 //在使用地方调用

    7 $this.$setWs.initWebSocket();8

    9 //在需要使用服务端推送过来的消息时

    10 //在computed方法声明

    11 getWsMsg() {12 //在核心代码接收到的服务端信息存储到vuex的属性

    13 return this.$store.state.webSocketMsg14 }15 //在watch方法 监听 getWsMsg

    16 getWsMsg: function(data, val) {17 console.log(data);18 //.......

    19 }

    此代码为本博主原创,转载请注明出处(支持原创! 谢谢~)

    凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~

    凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~

    凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~

    凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~

    凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~凑字数~

    展开全文
  • WebSocket接收后台实时消息推送 加入心跳包机制,避免自动断开连接! 哇 完整 上码. let ws = null, timeout1 = null, //心跳定时器 timeout2 = null,//断开重新连接定时器 timeout3 = null,// 重连失败断开连接...
  • Websocket原理 什么是webSocketwebSocket是一种在单个TCP连接上进行全双工通信的协议 客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。 浏览器和服务器只需要完成一次握手,两者...
  • 安装pip install websocket-client先来看一下,长连接调用方式:ws = websocket.WebSocketApp("ws://echo.websocket.org/",on_message = on_message,on_error = on_error,on_close = on_close)ws.on_open = on_...
  • Python实现WebSocket服务器(心跳检查、进程通信)心跳检查进程通信WebSocket完整代码参考文档 心跳检查 websocket适用于高频、服务端主动推送的场景需求,所以采用TCP长连接模式,长连接需要保活,即确保连接在被...
  • 然后想到建立一个长连接,在app端写一个长连接(用Socket或者WebSocket),并加入心跳检测,定期的去检测长连接是否连接正常,如果连接中断,执行重新连接。于是乎自己写了个Socket的长连接,加入了心跳检测。但是等...
  • 最近搞好论文,对其中的WebSocket中相对比较实用的技术做一个总结,这个东西之前是用来作前后台的监控数据的实时通信,主要记录一下心跳包和重连的过程,websocket中的心跳这里是通过客户端定义一个定时器...
  • websocket心跳机制

    2020-12-31 12:53:12
    什么是websocket?WebSocket 协议在2008年诞生,2011年成为国际标准。所有浏览器都已经支持了。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,403
精华内容 561
关键字:

websocket加入心跳包