我拼命尝试将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()
搬运工-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端口 - 一切都会正常工作。
答案 0 :(得分: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;
}
答案 1 :(得分:0)
我也有这个问题,并认为它与Nginx有关,但这是一条红鲱鱼。
就我而言,我的代码在频道上发送消息时会定期引发异常。当我介绍了Nginx并关闭了“死”通道(AFAIK)时,这才变得显而易见。但是,这在我看来像是一个超时,因此我检查了代理超时和各种情况。
最终,我在代码中添加了更多日志记录,并意识到该错误实际上部分是由以下示例引起的:
async_to_sync(channel_layer.group_send)(
'notifications', {
"type": "notification",
"data": some_packet
}
)
我的消费者在收到此消息时期望有一个“文本”属性,但处理得不好。
然后关闭套接字,Nginx丢弃了它,我认为这是Nginx / Daphne / Docker-networking出现了2天的问题。
希望这对某人有帮助。