Skip to content

WebSockets

Starlette 包含一个 WebSocket 类,其作用与 HTTP 请求类似,但允许在 WebSocket 上发送和接收数据。

WebSocket

签名: WebSocket(scope, receive=None, send=None)

from starlette.websockets import WebSocket


async def app(scope, receive, send):
    websocket = WebSocket(scope=scope, receive=receive, send=send)
    await websocket.accept()
    await websocket.send_text('Hello, world!')
    await websocket.close()

WebSockets 提供了一个映射接口,因此您可以像使用 scope 一样使用它们。

例如: websocket['path'] 将返回 ASGI 路径。

统一资源定位符(通常也被简称为网址)

WebSocket URL 以 websocket.url 进行访问。

该属性实际上是 str 的一个子类,并且还公开了可以从 URL 中解析出的所有组件。

例如: websocket.url.pathwebsocket.url.portwebsocket.url.scheme

标题

标头被暴露为不可变、不区分大小写的多字典。

例如: websocket.headers['sec-websocket-version']

查询参数

查询参数作为不可变的多重字典被暴露出来。

例如: websocket.query_params['search']

路径参数

路由器路径参数作为字典接口被暴露出来。

例如: websocket.path_params['username']

接受连接

  • await websocket.accept(subprotocol=None, headers=None)

发送数据

  • await websocket.send_text(data)
  • await websocket.send_bytes(data)
  • await websocket.send_json(data)

从 0.10.0 版本起,JSON 消息默认通过文本数据帧发送。使用 websocket.send_json(data, mode="binary") 通过二进制数据帧发送 JSON。

接收数据

  • await websocket.receive_text()
  • await websocket.receive_bytes()
  • await websocket.receive_json()

该文本“May raise starlette.websockets.WebSocketDisconnect() .”似乎不太符合常规的语义表达,难以进行准确的中文翻译。如果您有更多的上下文信息或确认文本内容的准确性,我将尽力为您提供更满意的翻译。目前按照字面直译的话,只能译为:“可能提高 starlette.websockets.WebSocketDisconnect() 。”但这个翻译可能不太符合实际意义。

从 0.10.0 版本起,JSON 消息默认通过文本数据帧接收。使用 websocket.receive_json(data, mode="binary") 通过二进制数据帧接收 JSON。

迭代数据

  • websocket.iter_text()
  • websocket.iter_bytes()
  • websocket.iter_json()

receive_textreceive_bytesreceive_json 类似,但返回一个异步迭代器。

from starlette.websockets import WebSocket


async def app(scope, receive, send):
    websocket = WebSocket(scope=scope, receive=receive, send=send)
    await websocket.accept()
    async for message in websocket.iter_text():
        await websocket.send_text(f"Message text was: {message}")
    await websocket.close()

starlette.websockets.WebSocketDisconnect 被提升时,迭代器将退出。

关闭连接

  • await websocket.close(code=1000, reason=None)

发送和接收消息

如果您需要发送或接收原始 ASGI 消息,那么您应该使用 websocket.send()websocket.receive() ,而不是使用原始的 sendreceive 可调用对象。这样可以确保 WebSocket 的状态得到正确更新。

  • await websocket.send(message)
  • await websocket.receive()

发送拒绝响应

如果您在调用 websocket.accept() 之前调用 websocket.close() ,那么服务器将自动向客户端发送 HTTP 403 错误。

如果您想要发送不同的错误响应,可以使用 websocket.send_denial_response() 方法。这样将发送响应并随后关闭连接。

  • await websocket.send_denial_response(response)

这要求 ASGI 服务器支持 WebSocket 拒绝响应扩展。如果不支持,将引发 RuntimeError 错误。