zoukankan      html  css  js  c++  java
  • Nginx代理webSocket时60s自动断开, 怎么保持长连接

    可以进入系统测试:在线聊天

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

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

    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初始化的内容.

    原文地址:https://blog.csdn.net/cm786526/article/details/79939687

  • 相关阅读:
    xxx.app已损坏,打不开.你应该将它移到废纸篓-已解决
    如何培训新进的软件测试人员
    测试Leader,这些你都做到了嘛?
    GitHub无法访问、443 Operation timed out的解决办法
    GitHub使用Personal access token
    运行Windows虚拟机时,风扇狂转的问题
    使用Keras做OCR时报错:ValueError: Tensor Tensor is not an element of this graph
    Windows虚拟机中无法传输Arduino程序的问题
    Python3中遇到UnicodeEncodeError: 'ascii' codec can't encode characters in ordinal not in range(128)
    实际应用中遇到TimedRotatingFileHandler不滚动的问题
  • 原文地址:https://www.cnblogs.com/interdrp/p/12148200.html
Copyright © 2011-2022 走看看