You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Elastic Beanstalk部署Flask-SocketIO后Socket连接失败及代理配置问题

Flask-SocketIO在AWS Elastic Beanstalk无法连接的解决方案

问题根源

  1. 代理配置报错:你用的ProxyServer: 'none'仅适用于旧版Amazon Linux(AMI),新版Amazon Linux 2的EB Python平台不支持该配置,因此部署时触发错误。
  2. Socket连接失败:默认Apache代理未转发WebSocket所需的Upgrade和Connection请求头,导致握手失败;同时本地与EB的端口配置不匹配,也会引发连接异常。

分步解决

一、修复代理配置(二选一)

方案1:保留Apache代理,添加WebSocket转发规则

修改.ebextensions/wsgi_custom.conf,补充WebSocket转发逻辑:

files:
  "/etc/httpd/conf.d/wsgi_custom.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      WSGIApplicationGroup %{GLOBAL}
      # 转发WebSocket请求到gunicorn
      RewriteEngine On
      RewriteCond %{HTTP:Upgrade} =websocket [NC]
      RewriteRule /(.*) ws://localhost:8000/$1 [P,L]
      RewriteCond %{HTTP:Upgrade} !=websocket [NC]
      RewriteRule /(.*) http://localhost:8000/$1 [P,L]

packages: 
    yum:
        python3-devel: [] 
        gcc: [] 
        gawk: []
        polkit: []
        gcc-c++: []
        make: []

该配置让Apache识别WebSocket请求,自动转发到gunicorn监听的8000端口。

方案2:禁用代理,让gunicorn直接监听80端口

  1. 删除之前错误的ProxyServer: 'none'配置,在.ebextensions中添加端口设置:
option_settings:
  aws:elasticbeanstalk:environment:process:default:
    Port: "80"
    HealthCheckPath: "/hello_world"
  1. 修改Procfile,指定gunicorn监听80端口:
web: gunicorn --worker-class eventlet -w 1 --bind 0.0.0.0:80 app:app

这样EB会跳过Apache代理,直接把流量打到gunicorn服务上。


二、修正SocketIO相关代码

  1. 明确指定异步模式:在__init__.py中给SocketIO实例加上async_mode='eventlet',避免自动检测出错:
from flask import Flask
from flask_cors import CORS
from flask_socketio import SocketIO

# 强制使用eventlet作为异步引擎
socketio = SocketIO(cors_allowed_origins="*", async_mode='eventlet')

def create_app(config_file='config.py'):
    app = Flask(__name__, static_url_path='/fx_app/media', static_folder='media')
    CORS(app, resources={r"/socket.io/*": {"origins": "*"}})
    app.config.from_pyfile(config_file)
    with app.app_context():
        socketio.init_app(app)
        from .socket_events import configure_socket_events
        configure_socket_events(socketio)
        return app
  1. 本地启动改用socketio.run:修改app.py的启动逻辑,确保本地开发也用eventlet运行:
from fx_app import create_app, socketio

app = create_app()

@app.route('/hello_world')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    # 用socketio.run替代app.run,保证eventlet正确加载
    socketio.run(app, host='0.0.0.0', port=8081, debug=True, load_dotenv=True)
  1. 锁定依赖版本:在requirements.txt中指定兼容的包版本,避免依赖冲突:
flask==2.3.3
flask-socketio==5.3.5
eventlet==0.33.3
flask-cors==4.0.0
gunicorn==21.2.0

三、验证部署

  1. 部署后查看EB日志,确认gunicorn以eventlet worker启动,监听端口和配置一致。
  2. 客户端连接时,直接用EB环境域名(比如https://your-env.elasticbeanstalk.com),不要手动加端口。
  3. 检查浏览器控制台的网络请求,确认/socket.io/的请求返回200,WebSocket握手状态码为101。

内容的提问来源于stack exchange,提问作者Umar Farooq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:30:07