文章分享

开放、平等、协作、快速、分享

当前位置:首页>文章分享

Nginx代理webSocket时60s自动断开, 怎么保持长连接

摘录:HCTech 无锡和控电子   时间:2020-08-07   访问量:4509

利用nginx代理websocket的时候,发现客户端和服务器握手成功后,如果在60s时间内没有数据交互,连接就会自动断开,如下图:

blob.png


为了保持长连接,可以采取来两种方式.


1.nginx.conf 文件里location 中的proxy_read_timeout 默认60s断开,可以把他设置大一点,你可以设置成自己需要的时间,我这里设置的是十分钟(600s).


nginx配置如下:


server {

listen 80;

server_name carrefourzone.senguo.cc;

#error_page 502 /static/502.html;

 

location /static/ {

   root /home/chenming/Carrefour/carrefour.senguo.cc/source;

   expires 7d;

        }

 

location / {

   proxy_pass_header Server;

   proxy_set_header Host $http_host;

   proxy_redirect off;

   proxy_set_header X-Real-IP $remote_addr;

   proxy_set_header X-Scheme $scheme;

   proxy_pass       http://127.0.0.1:9887;

   proxy_http_version  1.1;

   proxy_set_header    Upgrade    "websocket";

   proxy_set_header    Connection "Upgrade";

   proxy_read_timeout 600s; 

}

}

按照上述方法设置好后,我们可以发现,如果在10分钟之内没有数据交互的话,websocket连接就会自动断开,所以这种方式还是有点问题,如果我页面停留时间超过十分钟而且又没有数据交互的话,连接还是会断开的,所以需要同时结合第二种方法.


上面nginx配置的时候还出了一个小插曲,微改了nginx配置之后,没有重启nginx服务,导致设置的过期时间一直没有生效,所以需要用 sudo nginx -s reload  重启nginx服务


2.在nginx延长超时时间的基础上,前端在超时时间内发心跳包,刷新再读时间,前端具体实现见如下代码(此处代码包含了前端整个websocket的实现过程,其中红色重点标注了发心跳包的内容):


// websocket连接

var websocket_connected_count = 0;

var onclose_connected_count = 0;

function newWebSocket(){

    var websocket = null;

    // 判断当前环境是否支持websocket

    if(window.WebSocket){

        if(!websocket){

            var ws_url ="wss://"+domain+"/updatewebsocket";

            websocket = new WebSocket(ws_url);

        }

    }else{

        Tip("not support websocket");

    }

 

    // 连接成功建立的回调方法

    websocket.onopen = function(e){

        heartCheck.reset().start();   // 成功建立连接后,重置心跳检测

        Tip("connected successfully")

    }

    // 连接发生错误,连接错误时会继续尝试发起连接(尝试5次)

    websocket.onerror = function() {

        console.log("onerror连接发生错误")

        websocket_connected_count++;

        if(websocket_connected_count <= 5){

            newWebSocket()

        }

    }

    // 接受到消息的回调方法

    websocket.onmessage = function(e){

        console.log("接受到消息了")

        heartCheck.reset().start();    // 如果获取到消息,说明连接是正常的,重置心跳检测

        var message = e.data;

        if(message){

           //执行接收到消息的操作,一般是刷新UI

        }

    }

 

    // 接受到服务端关闭连接时的回调方法

    websocket.onclose = function(){

        Tip("onclose断开连接");

    }

    // 监听窗口事件,当窗口关闭时,主动断开websocket连接,防止连接没断开就关闭窗口,server端报错

    window.onbeforeunload = function(){

        websocket.close();

    }

 

    // 心跳检测, 每隔一段时间检测连接状态,如果处于连接中,就向server端主动发送消息,来重置server端与客户端的最大连接时间,如果已经断开了,发起重连。

    var heartCheck = {

        timeout: 55000,        // 9分钟发一次心跳,比server端设置的连接时间稍微小一点,在接近断开的情况下以通信的方式去重置连接时间。

        serverTimeoutObj: null,

        reset: function(){

            clearTimeout(this.timeoutObj);

            clearTimeout(this.serverTimeoutObj);

            return this;

        },

        start: function(){

            var self = this;

            this.serverTimeoutObj = setInterval(function(){

                if(websocket.readyState == 1){

                    console.log("连接状态,发送消息保持连接");

                    websocket.send("ping");

                    heartCheck.reset().start();    // 如果获取到消息,说明连接是正常的,重置心跳检测

                }else{

                    console.log("断开状态,尝试重连");

                    newWebSocket();

                }

            }, this.timeout)

        }

    }

}


上述过程就是保持长连接的过程,前端部分也包含了大部分websocket初始化的内容

————————————————

版权声明:本文为CSDN博主「晴识明月」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/cm786526/article/details/79939687


上一篇:WebSocket协议—从顶层到底层的实现原理

下一篇:彻底理解cookie,session,token

在线咨询

点击这里给我发消息 售前咨询专员

点击这里给我发消息 售后服务专员

在线咨询

免费通话

24小时免费咨询

请输入您的联系电话,座机请加区号

免费通话

微信扫一扫

微信联系
返回顶部