为什么Nginx代理websocket后30秒连接会断开?而且在这30s内响应不了其他请求

在centos上部署了一个项目,用Nginx来代理websocket,但是websocket连上后30s就会自动断开,在网上查了说Nginx的proxy_read_timeout要设置大点,下面是nginx.conf中关于websocket的配置:

location / {
    proxy_set_header Host $host;
    proxy_pass http://172.16.137.234:8000;
    proxy_connect_timeout 4;
    proxy_read_timeout 86400s;
    proxy_send_timeout 86400s;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

我试了无论proxy_read_timeout设置多少,连接还是会在30s的时候自动断开。

我也试了用心跳来保持websocket的连接,下面是代码
前端:

href = "ws://"+baseIP+"/user/connect/"
ws = new WebSocket(href)
var heartCheck = {
    timeout: 5000,        //5秒发一次心跳
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        return this;
    },
    start: function(){
        var self = this;
        this.timeoutObj = setTimeout(function(){
            ws.send("keepalive");
            console.log("发送:keepalive")
            self.serverTimeoutObj = setTimeout(function(){
                ws.close();     
            }, self.timeout)
        }, this.timeout)
    }
}
ws.onopen = function(){
    console.log("websocket已连接")
    heartCheck.reset().start()
    ws.send(user_id)
}
ws.onmessage = function(evt){
    heartCheck.reset().start();
    if (evt.data != "keepalive"){
        msg = JSON.parse(evt.data)
        that.messageNotice(msg)
    }else{
        console.log("接收:"+evt.data)
    }
}
ws.onclose = function(e){
    console.log("websocket已断开")
    console.log(e)
}

这是从网上抄下来的,我设置的是5秒发一次心跳。

后台:

def user_ws_connect(request):
    """
    接收websocket请求并保存
    :param request:
    :return:
    """
    if request.is_websocket():
        while True:  
            message = request.websocket.wait()
            if not message:
                break
            if message.decode() == "keepalive":
                request.websocket.send("keepalive")
            else:
                ...

页面控制台输出信息:
image.png
发送接收6次,也就是30s后连接就断开了。
而且在这30秒内网页响应不了其他请求,必须要等到websocket连接断开才会响应。。。。。
我在开发环境没用Nginx就不会有这种情况,有人知道是怎么回事吗? T-T

阅读 8.8k
2 个回答

已经解决。
是gunicorn的原因,gunicorn启动配置项要加上 --worker-class=gevent
完整命令:

gunicorn --worker-class=gevent yourapp.wsgi:application
新手上路,请多包涵

你好博主,想咨询您一下您这个后台是用的Python吗,我也碰到了这个问题,就是Python后台,然后用Nginx代理websocket后,浏览器页面已经返回了101状态码,但是刚连上就立马断开,我用的是flask-socketio。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题