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()

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

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


URL

WebSocket 的 URL 可以通过 websocket.url 访问。

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

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


Headers

请求头以不可变的大小写不敏感多重字典形式暴露。

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


查询参数(Query Parameters)

查询参数以不可变的多重字典形式暴露。

例如:websocket.query_params['search']


路径参数(Path Parameters)

路由器路径参数以字典接口的形式暴露。

例如:websocket.path_params['username']


接受连接

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

该方法用于接受 WebSocket 连接,可选参数包括:

  • subprotocol:指定子协议的名称。
  • headers:附加自定义头信息作为字典传入。

发送数据

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

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

接收数据

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

可能会引发 starlette.websockets.WebSocketDisconnect() 异常。

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

数据迭代

  • 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 异常。