WebSocket断线重连记录

断线重连与心跳包重连

公司最近在做一个抽奖的运用,年会快到了嘛
应用基于微信页来做开发的,其中有一个功能是需要即时交互,在团队定下的方案中,就用socket,于是我便和websocket会面了;

runoob上的例子:http://www.runoob.com/html/html5-websocket.html
看到网上html websocket很多的代码demo都是这样5行代码一个模子:

1.实例化WebSocket对象 
var old = new WebSocket("ws://xxxx.xxxxx.xxx:xxxx");
2.回调事件的处理
old.onerror = function () {}
old.onopen = function(){}
old.onmessage = function (evt){}
old.onclose = function () {}

我碰到了重连失败的这个问题(websocket断开连不上,断网情况连不上),我尝试这样处理重连,但无效:

//连接关闭的回调方法
//连接关闭的回调方法
old.onclose = function () {
    //alert("flow.html:WebSocket失效连接关闭");
    console.log("flow.html:WebSocket失效连接关闭");

    //1,reload 方法,该方法强迫浏览器刷新当前页面(可行,但拙)
    window.location.reload();

    //2.重新new(不可行)
    /*xin = new WebSocket("ws://xxxx.xxxxx.xxx:xxxx");
    old = null;
    old = xin;*/
}

暂时拙用了html中window.location.reload();在当前html页websocket失效的时候再重新加载,当然这是不行的;
于是便暂放了一下,先用html reload()的方式顶着先,一定会找到方法;

网上找个重连包吧,搜的一下,github上找到这个:
https://github.com/joewalnes/reconnecting-websocket
reconnecting-websocket.js
reconnecting-websocket.min.js

引入
<script type="text/javascript" src="xxxx/reconnecting-websocket.js"></script>
// 打开一个 web socket,自动提交表单到后台controller,以绑定client_id
var url = "ws://xxx.xxxxx.xxx:xxxx";
//var old = new WebSocket(url);
var old = new ReconnectingWebSocket(url);
old.debug = true;
old.timeoutInterval = 5400;

打开手机,打开秒表(噔噔噔…),测试看看到底有没有效果:

16:17 开始,有效,收到即时消息
16:20 有效,收到即时消息
16:35 失效,未收到即时消息
用时17:54 59;
-》重连失败!(吼吼啊啊啊,我要疯了...难道是用错了??)

————————————————————-2018年01月31日 11:59:54—————————————————————

这个重连的问题困扰我很多天了,想不明白是个啥原因,也不知道怎么做,有点灰心,现在
5分钟就断开了,然后连不了…唉!!
这里写图片描述

再测一次吧,这个代码:

var websocket = new ReconnectingWebSocket(url);
//websocket.debug = true;//之前打了个true,不会是debug true值导致的重连无效吧???被自己坑了??!!!
websocket.debug = false;
websocket.timeoutInterval = 3000;

18:18 ok
18:20 ok
18:22 ok  //中间手机熄了一次屏
18:25 ok
18:27 ok
18:31 no!
时长约13Min;

再测一次吧,这个代码2:

var websocket = new ReconnectingWebSocket(url);
//websocket.debug = true;
//websocket.debug = false;
//websocket.timeoutInterval = 3000;

18:38 ok
18:40 ok
18:45 no(此时已经断了,网络不稳定原因,连发了3次,html websocket没有收到消息),此时接着页面刷新测->
18:45 ok
18:50 ok
18:55 ok
19:00 ok(关掉屏幕Android休眠)
19:07 断了! (这次时长20分钟,说明它还可以更长时间的连接,没有问题)
19:10 
19:15 
19:20 
19:25 
19:30 

排原因:微信浏览器缓存,缓存了上次修改的js,css,清除缓存:退出微信号,kill应用进程,再登录微信,访问html页面;
休眠的问题!:
相关博客:
1.websocket聊天室,一开始能用聊天,手机休眠后,就不能用了
2.Android锁屏休眠唤醒后,为什么WebSocket和Ajax在后台不能正常工作
3.websocket中wss在ios中,无法断开重连
4.html5+javascript 有什么方法能让手机浏览器不休眠吗?

那就测休眠:

var websocket = new ReconnectingWebSocket(url);
//websocket.debug = true;
//websocket.debug = false;
//websocket.timeoutInterval = 3000;
19:24 开始休眠(android huawei)
19:29 断了。 

android休眠后,重新开启时,浏览器如何告诉html,android设备已经不是休眠状态了?有这样的东西吗??这种事件检测已经不是浏览器支持的能力了…这种能力的支持对用户手机是相当不安全的,此事告一段落,原来是这个原因…

结论:只有在android/ios手机设备不休眠的先决条件下,html websocket才能重连;(结论是错误的!…记2018年 02月 06日 星期二 08:55:57 CST)
————————————————————-2018年 02月 03日 星期六 17:27:50 CST—————————————————————

读者看到,如有误,请纠正,感谢不尽。

这个问题还没解决,手机不休眠下重连,还是失败的,根本不知道它什么时候会失效,就是断了,连不上;
————————————————————-2018年 02月 05日 星期一 15:24:17 CST—————————————————————

心跳包重连?
http://www.voidcn.com/article/p-zshodvff-mm.html
http://www.voidcn.com/article/p-trguhbme-bnu.html
断线重连?

心跳包重连CODE:

//====================================================心跳包重连CODE START=======================================
        var lockReconnect = false;  //避免ws重复连接
        var ws = null;          // 判断当前浏览器是否支持WebSocket
        var wsUrl = "ws://xxx.xxxxx.xxx:xxxx";
        createWebSocket(wsUrl);   //连接ws

        function createWebSocket(url) {
            //x]alert("line83");
            try {
                if ('WebSocket' in window) {
                    //x]alert("line85");
                    ws = new WebSocket(url);
                } else if ('MozWebSocket' in window) {
                    //x]alert("line88");
                    ws = new MozWebSocket(url);
                } else {
                    //x]alert("line91");
                    layui.use(['layer'], function () {
                        var layer = layui.layer;
                        layer.alert("您的浏览器不支持websocket协议,建议使用新版谷歌、火狐等浏览器,请勿使用IE10以下浏览器,360浏览器请使用极速模式,不要使用兼容模式!");
                    });
                }
                initEventHandle();
            } catch (e) {
                //x]alert("line98");
                reconnect(url);
                console.log(e);
            }
        }

        function initEventHandle() {
            ws.onclose = function () {
                console.log("llws连接关闭!" + new Date().toUTCString());
                //x]alert("llws连接关闭!" + new Date().toUTCString());
                reconnect(wsUrl);
            };
            ws.onerror = function () {
                console.log("llws连接错误!");
                //x]alert("llws连接错误!");
                reconnect(wsUrl);
            };
            ws.onopen = function () {
                //x]alert("line117");
                heartCheck.reset().start();      //心跳检测重置
                console.log("llws连接成功!" + new Date().toUTCString());
                //x]alert("llws连接成功!" + new Date().toUTCString());
            };
            ws.onmessage = function (event) {    //如果获取到消息,心跳检测重置
                heartCheck.reset().start();      //拿到任何消息都说明当前连接是正常的
                /*iconsole.log("llws收到消息啦:" + event.data);
                f(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);
                        }
                    };
                }*/

                var eventData = event.data;
                handMsg(eventData);
            };
        }

        // 监听窗口关闭事件,当窗口关闭时,主动去关闭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分钟发一次心跳
            //timeout: 3600,        //1分钟发一次心跳
            timeout: 10800,        //3分钟发一次心跳
            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 () {
                        //如果超过一定时间还没重置,说明后端主动断开了
                        //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                        ws.close();     
                    },self.timeout)
                },this.timeout)
            }
        }


        //====================================================心跳包重连CODE END=========================================

        //处理消息
        function handMsg(evtdata) {}

(3分钟发一次心跳)测试:

14:16  ok
14:19  ok
14:21  ok
14:25  ok
14:28  ok
14:36  ok
15:04  ok
16:00  

终于ok,泥妹的,中文逗号这里写图片描述
————————————————————2018年 02月 06日 星期二 14:12:48 CST—————————————————————

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dnbug Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值