生产环境Flask SocketIO连接失败 本地运行正常该如何解决?
第一步:回滚ASGI相关修改,修正WSGI配置
你完全不需要将WSGI转ASGI,gunicorn+eventlet组合原生支持flask-socketio的WebSocket协议,转ASGI反而会出现协议不兼容的问题,你遇到的TypeError: __call__() missing 1 required positional argument: 'send'就是因为gunicorn是WSGI服务器,无法调用ASGI应用导致的。
回滚后的wsgi.py需要在最开头添加eventlet猴子补丁,同时要和前端指定的path保持一致,修正后代码如下:
# 最开头先打补丁,必须放在所有导入之前 import eventlet eventlet.monkey_patch() from chat import app from dotenv import load_dotenv, find_dotenv from flask_socketio import SocketIO from messages.socket import socket_handle load_dotenv(find_dotenv()) app = app(settings="chat.settings.dev") # 和前端path参数保持一致,添加path配置 socket = SocketIO(app, cors_allowed_origins=app.config['ALLOWED_CORS'], path='/chat/socket.io') socket_handle(socket)
启动命令回滚为原来的版本即可:
gunicorn --worker-class eventlet -w 1 --bind 0.0.0.0:8000 --timeout 500 --keep-alive 500 wsgi:app
第二步:检查反向代理配置(Nginx/Apache)
90%以上的同类问题都是因为生产环境的反向代理没有配置WebSocket转发规则导致的,如果你用了Nginx作为反向代理,需要在对应站点的配置块中添加以下规则:
location /chat/socket.io { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; # 按需调整超时时间 proxy_read_timeout 3600s; proxy_send_timeout 3600s; }
如果用的是Apache,需要开启proxy_wstunnel模块,再配置对应的WebSocket转发规则。
第三步:修正前端连接配置
你当前的连接参数写法有冗余,可能会导致路径匹配错误,修正为以下写法即可:
// 第一个参数直接写服务端根地址即可,path参数已经指定了socket.io的路由前缀 var socket = io('http://server-ip', {"path" : "/chat/socket.io"});
第四步:确认版本兼容性
- 前端Socket.IO 4.x客户端对应后端python-socketio 5.x版本,不要出现大版本跨级不兼容的情况
- eventlet版本不要过旧,建议升级到最新稳定版
内容的提问来源于stack exchange,提问作者AmrElsayed
相关产品推荐
相关产品推荐

