【问题标题】:Docker nginx websocket proxy== client closed connection while waiting for requestDocker nginx websocket proxy==客户端在等待请求时关闭连接
【发布时间】:2018-07-21 08:32:49
【问题描述】:

我拼命尝试将 nginx 代理设置为 websocket。 Websocket 连接但我得到了

2018/02/10 19:30:34 [info] 7#7: *238 客户端关闭连接,而 等待请求,客户端:172.18.0.1,服务器:0.0.0.0:8888

这是最小的例子:

nginx.conf

worker_processes  1;

events {
    worker_connections  1024;
}
error_log /dev/stdout debug;

http  {
    resolver 127.0.0.11 ipv6=off;
    include       mime.types;
    access_log /dev/stdout;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream tornado {
      server ws:8888;
      #server ws:8889; I may add another upstream here
    }

    server {
         add_header X-Frame-Options SAMEORIGIN;
         add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";

        listen 8888;

        server_name pychat.org;
        charset     utf-8;
        client_max_body_size 75M;

        location / {
             proxy_pass http://tornado/;
             #>>> otherwise error 400
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
             proxy_set_header Host $host;
             proxy_send_timeout 330;
             proxy_read_timeout 330;
             #>>>>>>
             #proxy_redirect off;
             proxy_set_header X-Real-IP $remote_addr;
             #proxy_set_header X-Scheme $scheme;
        }

    }
}

server.py

import tornado.ioloop
from tornado.websocket import WebSocketHandler, WebSocketClosedError
from tornado import web
class MainHandler(WebSocketHandler):

    def open(self):
        print("WebSocket opened")

    def on_message(self, message):
        print("ws mess" +  message)
        self.write_message(u"You said: " + message)

    def on_close(self):
        print("WebSocket closed")

    def check_origin(self, origin):
        return True

def make_app():
    return tornado.web.Application([
        (r'.*', MainHandler),
    ])

if __name__ == "__main__":
    app = make_app()
    app.listen(8888)
    tornado.ioloop.IOLoop.current().start()

docker-compose.yml

version: '2.3'
services:
  nginx:
    build:
      context: ../
      dockerfile: ./dockerfilenginx
    ports:
     - 8888:8888
  ws:
    build:
      context: ../
      dockerfile: ./docker/Dockerfilews

Dockerfilenginx

FROM alpine:3.6
RUN apk update &&\
apk add vim nginx ca-certificates wget && update-ca-certificates
COPY ./docker/nginx-test.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "pid /tmp/nginx.pid; daemon off;"]

Dockerfilews

FROM alpine:3.6
RUN apk update &&\
 apk add python3 &&\
pip3 install tornado
WORKDIR /usr/src
COPY ./server.py /usr/src
CMD python3 server.py

然后尝试打开一个 WebSocket 到服务器,例如从浏览器控制台(shift+ctrl+i)。

ws = new WebSocket('ws://localhost:8888')
ws.send("wsdata")

如果我删除 nginx 代理并在 docker 上公开 websocket 端口 - 一切都会正常工作。

【问题讨论】:

    标签: docker nginx websocket


    【解决方案1】:

    你能试试这个 nginx 的代理配置吗,我用它来 django 和 daphne

    proxy_http_version 1.1;解决了这个问题。

    location / {
        proxy_pass http://ws:8888;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    
        proxy_redirect     off;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
    }
    

    【讨论】:

    • 它与我的配置没有什么不同。我试过了,结果一样。此配置在没有 docker 的情况下可以正常工作。在 docker 里面,我得到了我写的东西。
    • 你试过没有 SSL 的代理(只是 ws://)
    • 是的,没关系,没有 ssl 就不行了。
    • 当您尝试使用 javascript 访问服务器时,您能否发布来自 nginx(和 ws)的日志
    【解决方案2】:

    我也遇到了这个问题,还以为跟 Nginx 有关系,但这是个转移话题。

    就我而言,我的代码在频道上发送消息时会定期引发异常。这只有在我介绍 Nginx 时才变得明显,它关闭了“死”通道(AFAIK)。然而,这对我来说似乎是超时,所以我检查了代理超时和各种事情。

    最终,我在代码中添加了更多日志记录,并意识到错误实际上部分是由以下(示例)引起的:

    async_to_sync(channel_layer.group_send)(
                            'notifications', {
                                "type": "notification",
                                "data": some_packet
                            }
                        )
    

    收到此消息时,我的消费者期待一个“文本”属性,但它没有很好地处理它。

    然后套接字关闭,Nginx 将其丢弃,我认为这是 Nginx/Daphne/Docker-networking 2 天的问题。

    希望这对某人有所帮助。

    【讨论】:

    • 有问题吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2018-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    相关资源
    最近更新 更多