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
相关产品推荐
相关产品推荐

