在Quart中使用Blueprints时WebSocket无法正常工作
解决Quart WebSocket蓝图结合Broker类出现400错误的问题
核心问题定位
你的代码存在两个关键错误,直接导致WebSocket连接返回400错误:
- Broker类方法缩进错误:
publish和subscribe函数未缩进在Broker类内部,属于独立函数而非类方法。调用broker.publish(message)时会触发属性错误,导致WebSocket握手失败。 - app.py缺少Quart实例初始化:提供的app.py代码未创建Quart应用实例,蓝图无法完成注册。
修复后的完整代码
1. 修复ws.py的Broker类结构
import asyncio from typing import AsyncGenerator class Broker: def __init__(self) -> None: self.connections = set() # 修正缩进,将publish转为类方法 async def publish(self, message: str) -> None: for connection in self.connections: await connection.put(message) # 修正缩进,将subscribe转为类方法 async def subscribe(self) -> AsyncGenerator[str, None]: connection = asyncio.Queue() self.connections.add(connection) try: while True: yield await connection.get() finally: self.connections.remove(connection) broker = Broker()
2. 完善app.py的应用初始化
from quart import Quart # 初始化Quart应用实例 app = Quart(__name__) if __name__ == "__main__": from routes.ws_bp import ws_bp as wbp app.register_blueprint(wbp) # 启动服务,开启debug方便排查问题 app.run(host="0.0.0.0", port=5000, debug=True)
3. 优化ws_bp.py的异步任务处理(可选)
使用Python 3.7+推荐的asyncio.create_task替代asyncio.ensure_future,并完善任务取消的异常处理:
from quart import Blueprint, websocket import asyncio from services.ws import broker ws_bp = Blueprint('ws_bp', __name__) async def _receive() -> None: while True: message = await websocket.receive() await broker.publish(message) @ws_bp.websocket('/ws') async def ws() -> None: task = None try: task = asyncio.create_task(_receive()) async for message in broker.subscribe(): await websocket.send(message) finally: if task: task.cancel() # 捕获任务取消的异常,避免报错 try: await task except asyncio.CancelledError: pass
验证修复
启动Quart服务后,前端WebSocket连接会正常建立,点击发送消息按钮时,消息会通过Broker广播到所有已连接的客户端。
内容的提问来源于stack exchange,提问作者Poi Son
相关产品推荐
相关产品推荐

