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

FastAPI 0.109+集成Socket.IO出现WebSocket路由错误问题排查

FastAPI 0.109+ 集成Socket.IO WebSocket服务连接异常问题排查与修复

问题原因

FastAPI 0.109版本开始重构了路由系统,对ASGI子应用的请求转发逻辑做了关键调整:

  • 原app.mount方式挂载socketio.ASGIApp时,FastAPI的路由中间件会优先将Socket.IO的HTTP握手请求判定为普通HTTP请求,找不到匹配路由就返回404
  • WebSocket连接阶段,新版本对ASGI消息的类型和顺序校验更严格,Socket.IO的响应消息不符合FastAPI的预期,触发RuntimeError

修复方案

方案1:改用socketio.AsyncServer.attach集成

放弃mount方式,直接将Socket.IO服务附加到FastAPI应用,指定Socket.IO的路径后缀:

from fastapi import FastAPI
import socketio

app = FastAPI()
# 初始化异步Socket.IO服务器,按需配置跨域
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")

# 定义Socket.IO事件
@sio.event
async def connect(sid, environ):
    print(f"客户端 {sid} 已连接")

@sio.event
async def disconnect(sid):
    print(f"客户端 {sid} 已断开")

# 附加到FastAPI应用,指定socket路径
sio.attach(app, socket_path="/ws/socket.io/")

客户端连接路径需改为:ws://your-domain:port/ws/socket.io/

方案2:用Starlette的Mount显式挂载ASGI应用

如果想保留原挂载路径结构,可通过Starlette的Mount类显式定义路由,绕过FastAPI默认的路由匹配逻辑:

from fastapi import FastAPI
from starlette.mount import Mount
import socketio

sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")
socket_app = socketio.ASGIApp(sio)

# 定义Socket.IO事件
@sio.event
async def connect(sid, environ):
    print(f"客户端 {sid} 已连接")

# 通过routes参数显式挂载
app = FastAPI(
    routes=[
        Mount("/ws", app=socket_app)
    ]
)

客户端连接路径保持原结构:ws://your-domain:port/ws/socket.io/

方案3:临时降级到FastAPI 0.108.0

如果暂时无法修改代码,可执行以下命令降级版本:

pip install fastapi==0.108.0

注意:这只是临时方案,长期来看建议适配新版本以获取安全和功能更新。

验证方法

  • 测试HTTP握手:执行curl http://localhost:8000/ws/socket.io/?EIO=4&transport=polling,应返回正常的握手响应而非404
  • 测试WebSocket连接:用前端或Postman连接ws://localhost:8000/ws/socket.io/,应成功建立连接,无RuntimeError触发

内容的提问来源于stack exchange,提问作者Eugene Snopok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:35:15