Перейти к основному содержимому

websocket

WebSocket

lihil поддерживает использование websocket, вы можете использовать WebSocketRoute.ws_handler для регистрации функции, которая обрабатывает websocket'ы.

from lihil import WebSocketRoute, WebSocket, Ignore, use

ws_route = WebSocketRoute("web_socket/{session_id}")

async def ws_factory(ws: Ignore[WebSocket]) -> Ignore[AsyncResource[WebSocket]]:
await ws.accept()
yield ws
await ws.close()

@ws_route.ws_handler
async def ws_handler(
ws: Annotated[WebSocket, use(ws_factory, reuse=False)],
session_id: str,
max_users: int,
):
assert session_id == "session123" and max_users == 5
await ws.send_text("Hello, world!")

lhl = Lihil()
lhl.include_routes(ws_route)

Тестирование

from lihil.vendors import TestClient # требует установки httpx

client = TestClient(lhl)
with client:
with client.websocket_connect(
"/web_socket/session123?max_users=5"
) as websocket:
data = websocket.receive_text()
assert data == "Hello, world!"

websocket против http

  • Обработчики WebSocket должны быть асинхронными — поскольку связь двунаправленная и управляемая событиями, обработчик должен использовать async def для поддержки неблокирующего взаимодействия.

  • WebSocket-соединения не поддерживают тела запросов так же, как HTTP — нет параметра Body во время рукопожатия. Все данные обмениваются после установления соединения, обычно через сообщения, отправляемые по протоколу WebSocket.

  • WebSocket'ы имеют состояние — в отличие от HTTP, который не имеет состояния, WebSocket-соединение сохраняется, позволяя непрерывную связь между клиентом и сервером. Это позволяет поддерживать состояние по каждому соединению (например, пользовательские сессии, данные в памяти).

  • WebSocket'ы используют другой жизненный цикл — они начинаются с HTTP-рукопожатия (обычно GET-запрос), затем обновляют протокол. После этого связь осуществляется по протоколу WebSocket, а не по HTTP.

  • Стандартные шаблоны запрос/ответ не применяются — WebSocket'ы основаны на сообщениях и поддерживают взаимодействие в реальном времени, поэтому традиционные концепции, такие как статус-коды, заголовки на сообщение или парсинг тела, не применяются напрямую после начального рукопожатия.