【发布时间】:2014-05-20 13:26:54
【问题描述】:
我在让 Nginx 与 Python Flask-socketio 库(基于 gevent)很好地配合使用时遇到了一些麻烦。目前,由于我们正在积极开发,我正试图让 Nginx 仅作为代理工作。对于发送页面,我可以通过直接运行 flask-socketio 应用程序或通过 gunicorn 运行来实现这一点。一个障碍:websocket 消息传递似乎不起作用。页面已成功托管和显示。但是,当我尝试使用 websockets 时,它们不起作用。它们足够活跃,以至于 websocket 认为它已连接,但它们不会发送消息。如果我删除 Nginx 代理,它们确实可以工作。当我尝试发送消息时,Firefox 给我这个错误:
Firefox 无法与位于 ws:///socket.io/1/websocket/ 的服务器建立连接。
其中网址是服务器所在的位置,唯一 ID 只是一堆随机数字。它似乎足以保持连接处于活动状态(例如,客户端认为它已连接),但无法通过 websocket 发送消息。我不得不认为这个问题与代理的某些部分有关,但是在调试问题可能是什么时遇到了很大的麻烦(部分原因是这是我第一次使用 Flask-socketIO 和 nginx)。我用于 nginx 的配置文件是:
user <user name>; ## This is set to the user name for the remote SSH session
worker_processes 5;
events {
worker_connections 1024; ## Default: 1024
}
http {
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] $status '
'"$request" $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
server {
listen 80;
server_name _;
location / {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
}
我将配置文件作为一般示例和 websocket 特定示例的混合体,但试图摆弄它并没有解决问题。另外,当我在 wsgi 模式下使用 Flask app.wsgi_app 时,我正在使用 werkzeug Proxy_Fix 调用。然而,我已经尝试过,不管有没有,都无济于事。如果有人有一些见解,我会全神贯注。
【问题讨论】:
-
你不应该在一些非根 URL 上代理你的 websocket 连接吗?如果一切都通过 websocket,你如何将 HTTP/JS 文件提供给客户端?
-
在生产中,nginx 将通过一些额外的配置设置来处理它。现在,在引擎盖下,Flask 正在处理所有事情。它有自己的静态文件路由功能。基本上,我正在使用 /js/、/static/ 等的一些端点,这些端点会导致相应的 Flask send_static_file 调用到这些端点的存储位置。便于测试,但显然不是你如何扩展任何东西。但是,这些都适用于上述 nginx 配置。只有 websocket 消息失败。
-
我现在已经解决了这个问题。这实际上是两个问题。首先,flask-socketio 希望套接字出现在“/socket.io”。其次,Ubuntu 12 使用了一个古老版本的 NginX。当我升级它时,通过执行清除和安装(常规 apt-get,而不是专门下载最新的稳定 repo),它在摆弄第一个问题时恢复到旧版本。将把它放在答案中并在今天晚些时候关闭它,以帮助其他可怜的迷失的灵魂。
标签: sockets nginx flask socket.io gevent-socketio