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

FastAPI挂载Socket.IO至/ws路由失效问题求助

问题原因分析

当把Socket.IO挂载到FastAPI的/ws子路由时,需同步调整服务器端Socket.IO路径配置、客户端连接路径,同时确保CORS策略覆盖子路由,否则会出现连接超时、命名空间错误或403禁止访问的问题。常见错误点:

  • 服务器端未指定Socket.IO子路径,导致客户端请求端点不存在
  • 客户端连接路径未匹配挂载的子路由
  • CORS配置未包含/ws相关路径,引发跨域禁止
  • 命名空间未正确绑定到子路由下的Socket.IO实例
解决方案代码示例

1. 修改server.py(FastAPI主文件)

将Socket.IO应用挂载到/ws,指定Socket.IO内部路径为/socket.io,并配置正确的CORS:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import sockets

app = FastAPI()

# 配置CORS(生产环境请限制具体域名)
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 挂载Socket.IO到/ws路由
app.mount("/ws", sockets.sio_app)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

2. 修改sockets.py(Socket.IO逻辑文件)

创建Socket.IO实例时指定path='/socket.io',确保命名空间正确注册:

from socketio import AsyncServer
from fastapi import FastAPI

# 创建AsyncServer,指定路径匹配挂载的子路由
sio = AsyncServer(
    async_mode="asgi",
    cors_allowed_origins="*",
    path="/socket.io"
)

# 绑定到ASGI应用
sio_app = FastAPI()
sio.mount_app(sio_app)

# 注册默认命名空间的事件
@sio.on("connect", namespace="/")
async def handle_connect(sid, environ):
    print(f"Client {sid} connected")

@sio.on("message", namespace="/")
async def handle_message(sid, data):
    print(f"Received message from {sid}: {data}")
    await sio.emit("response", f"Server received: {data}", room=sid)

3. 修改client.py(客户端代码)

调整连接URL为http://localhost:8000/ws,确保命名空间与服务器端一致:

import socketio

sio = socketio.Client()

@sio.on("connect")
def on_connect():
    print("Connected to server")
    sio.send("Hello from client")

@sio.on("response")
def on_response(data):
    print(f"Server response: {data}")

@sio.on("disconnect")
def on_disconnect():
    print("Disconnected from server")

if __name__ == "__main__":
    try:
        # 连接到/ws路由下的Socket.IO服务
        sio.connect("http://localhost:8000/ws", namespaces=["/"])
        sio.wait()
    except Exception as e:
        print(f"Connection error: {e}")
关键注意事项
  • 路径匹配:服务器端Socket.IO的path参数必须设为/socket.io,客户端连接URL直接用挂载的子路由/ws,Socket.IO会自动拼接为/ws/socket.io通信
  • CORS配置:FastAPI的CORSMiddleware需允许跨域请求,Socket.IO的AsyncServer也可单独配置cors_allowed_origins
  • 命名空间一致性:客户端连接时指定的命名空间必须和服务器端注册的完全一致(比如默认的/)
  • Postman测试:选择Socket.IO请求类型,输入URL为http://localhost:8000/ws,命名空间填/即可正常连接

内容的提问来源于stack exchange,提问作者bharat kundapur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:05:18