Websockets#

Websockets 从一个 GET 请求开始,该请求可以通过 101 协议升级到 websocket,或切换协议,响应或任何其他响应。在其他框架中,通常无法选择执行什么操作或如何响应,这是 Quart 的目标之一。此外,由于 websockets 与请求非常相似,Quart 旨在为 websockets 和请求提供类似的功能。

请求类似物#

Websockets 与 GET 请求非常相似,以至于仅仅扩展 Flask 请求 API 以包含 websocket 功能也很诱人。这可能会让 Flask-Sockets 或 Flask-SocketIO 的用户感到惊讶,因为它们是事实上的 Flask 标准。因此,我决定在现有请求功能的基础上引入 websocket 功能。

由于 websockets 与 GET 请求非常相似,因此为请求提供的所有功能生成类似物是有意义的。例如。 before_request()before_websocket(),并且除了请求上下文之外还存在 websocket 上下文。

响应或升级#

当考虑身份验证时,能够选择如何响应或是否升级的效用最明显。在下面的示例中,可以采用典型的 login_required 装饰器来阻止未经授权的 websocket 使用。

def login_required(func):
    @wraps(func)
    async def wrapper(*args, **kwargs):
        if websocket.authentication == (...):
            return await func(*args, **kwargs)
        else:
            abort(401)
    return wrapper

@app.websocket('/ws')
@login_required
async def ws():
    while True:
        await websocket.receive()
        ...

Quart 还允许通过 accept() 手动发送接受响应 (101),因为这为框架用户提供了完全控制权。

注意

此功能仅适用于实现 Websocket Denial Response 扩展的 ASGI 服务器。如果服务器不支持此扩展,Quart 将指示服务器在没有响应的情况下关闭连接。Hypercorn 是推荐的 ASGI 服务器,支持此扩展。