问题描述
我正在使用 Nginx + Gunicorn + Flask_SocketIo + Docker。
我正在一个 EC2 实例上运行一个 Nginx 容器和一个 python/alpine 容器。
我使用 flask_SocketIo 每 5 秒向客户端页面发送一次信息,无需重新加载页面。
我的应用程序已启动并正在运行,但 Socket 未连接。所以我在客户端看到的错误是:WebSocket 握手期间的错误:意外的响应代码:400
我在服务器端从 Nginx 得到的消息是:
**69.xxx.xxx.xxx - - [20/Dec/2020:21:06:54 +0000] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 400 23 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/87.x.xxxx.xx Safari/537.36" "-"**
我的应用程序的作用是:
我尝试过的:
什么有效:
这是我的 Nginx 配置:
upstream nameOfApp {
server app:8080;
}
server {
listen 80;
server_name 54.xxx.xxx.xx;
server_name www.domain;
location / {
proxy_set_header Host $http_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-Proto $scheme;
proxy_pass http://nameOfApp;
}
location /socket.io/ {
proxy_set_header Host $http_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-Proto $scheme;
proxy_pass http://nameOfApp;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
}
这是我的 docker-compose
version: "3.7"
services:
app:
build:
context: ./App
dockerfile: Dockerfile
command: gunicorn mainApp.run:app --bind 0.0.0.0:8080
container_name: app
restart: always
environment:
- APP_NAME=CordLte
expose:
- 8080
Nginx:
build: ./Nginx
container_name: Nginx
restart: always
ports:
- '80:80'
depends_on:
- app
值得一提的是,我在客户端关闭了轮询。
var socket = io({transports: ['websocket'],upgrade: false});
Miguel 建议的更新:
我打开了 socket.io 记录器。
app | 627211f5e8984f13a467f051bc560a29: Sending packet MESSAGE data 0
app | 627211f5e8984f13a467f051bc560a29: Received request to upgrade to websocket
Nginx | 69.xxx.xxx.xxx - - [21/Dec/2020:11:41:44 +0000] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 400 23 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/87.x.xxxx.xx Safari/537.36" "-"
app | 129d66e4d815482cb0251c913e6cb004: Sending packet OPEN data {'sid': '129d66e4d815482cb0251c913e6cb004','upgrades': [],'pingTimeout': 60000,'pingInterval': 25000}
app | 129d66e4d815482cb0251c913e6cb004: Sending packet MESSAGE data 0
app | 129d66e4d815482cb0251c913e6cb004: Received request to upgrade to websocket
Nginx | 69.xxx.xxx.xxx - - [21/Dec/2020:11:41:50 +0000] "GET /socket.io/?EIO=3&transport=websocket HTTP/1.1" 400 23 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/87.x.xxxx.xx Safari/537.36" "-"
这是点击按钮时记录器的结果:
app | 1c0df226c9b14e8c8da8afe9bd1601c7: Sending packet MESSAGE data 2["message",{"data":["678",0]}]
app | 7bda92d2ea9a41c5abd22f4576d6a075: Sending packet MESSAGE data 2["message",0]}]
app | 1c0df226c9b14e8c8da8afe9bd1601c7: Client is gone,closing socket
app | 1c0df226c9b14e8c8da8afe9bd1601c7: Client is gone,closing socket
app | 7bda92d2ea9a41c5abd22f4576d6a075: Sending packet MESSAGE data 2["message",{"data":["680",0]}]
如果还有什么我可以澄清的,请告诉我
解决方法
几天后......我发现了我的问题。
我需要在 docker-compose 命令上添加 -k gevent
。我需要添加 gevent 来处理我的事件循环。 Gunicorn 使用同步工作类来处理请求,但它可以配置为使用 gevent。