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的实现过程,其中红色重点标注了发心跳包的内容):

    <script>
        $(document).ready(function () {
            window.websocket = {};
            var userId = 'zqh';
            var api = 'localhost:8080';
            var msg = 'hello websocket';
            var app = {
                /**
                 *初始化socket,判断是否支持webSocket
                 */
                initSocket: function () {
                    if ('WebSocket' in window) {
                        websocket = new WebSocket("ws://" + api + "/webscoket/ID=" + userId);
                    } else if ('MozWebSocket' in window) {
                        websocket = new MozWebSocket("ws://" + api + "/webscoket/ID=" + userId);
                    } else {
                        websocket = new SockJS("http://" + api + "/sockjs/webscoket/ID=" + userId);
                    }
                    app.state();
                },
                /**
                 * 状态
                 */
                state: function () {
                    // 打开连接时
                    websocket.onopen = function (evnt) {
                        heartCheck.reset().start();
                        console.log("websocket已启用");
                        document.getElementById("WebSocketStatus").innerText = "websocket已启用";
                    };

                    // 收到消息时
                    websocket.onmessage = function (event) {
                        heartCheck.reset().start();
                        document.getElementById("receivemsg").innerText = event.data;
                    };

                    //出错时
                    websocket.onerror = function (evnt) {
                        console.log("与后台握手出现问题!");
                    };

                    //关闭时
                    websocket.onclose = function (evnt) {
                        console.log("正在关闭 webSocket ");
                    };
                }
            };
            app.initSocket();
        });

        // 心跳检测,每隔一段时间检测连接状态,如果处于连接中,就像Server主动发送消息,来重置Server段与客户端的最大连接时间,如果已经断开,发起重连
        var heartCheck = {
            // 9分钟发起一次心跳,比Server端设置的连接时间稍微小一点,在接近断开的情况下以通信的方式去重置连接时间
            timeout: 550000,
            serverTimeoutObj: null,
            reset: function () {
                clearTimeout(this.serverTimeoutObj);
                return this;
            },
            start: function () {
                this.serverTimeoutObj = setInterval(function () {
                    if (websocket.readyState == 1) {
                        console.log("连接状态,发送消息保持连接");
                        websocket.send("ping");
                        // 如果获取到消息,说明连接正常,重置心跳检测
                        heartCheck.reset().start();
                    } else {
                        console.log("断开连接,尝试重连");
                        app.initSocket();;
                    }
                }, this.timeout)
            }
        };
        function send() {
            var msg = document.getElementById("sendmsg").value;
            heartCheck.reset().start();
            //发送消息
            websocket.send(msg);
        }
    </script>

上述过程就是保持长连接的过程。

参考文章:https://blog.csdn.net/cm786526/article/details/79939687

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值