microdot.websocket — підтримка WebSocket

WebSocket — це двостороннє постійне з’єднання поверх HTTP: після рукостискання оновлення клієнт і сервер обмінюються кадрованими повідомленнями через один і той самий сокет. Використовуйте їх тоді, коли камері та браузерному застосунку потрібен дуплексний трафік, якого SSE (одностороннє надсилання) та звичайне HTTP-опитування не можуть забезпечити ефективно.

class WebSocket

class microdot.websocket.WebSocket(request)

Дескриптор, який отримує маршрут. Передається обробникам як другий аргумент, коли використовується with_websocket(); не конструюйте безпосередньо.

Атрибути класу

max_message_length: int

Максимальний розмір корисного навантаження, який receive() прийме. Повідомлення більшого розміру генерують WebSocketError і закривають з’єднання. 0 вимикає перевірку (будьте обережні щодо атак на вичерпання пам’яті, якщо встановлюєте це значення). -1 (за замовчуванням) використовує Request.max_body_length.

CONT: int

Код операції кадру продовження, 0x0. Позначає кадр, що продовжує корисне навантаження попереднього кадру для того самого повідомлення. Microdot не генерує кадри продовження самостійно (кожне повідомлення надсилається як один кадр) і відхиляє їх під час отримання, проте константа доступна для застосунків, які реалізують власне кадрування.

TEXT: int

Код операції текстового кадру, 0x1. Код операції, який send() вибирає автоматично, коли data є str; корисне навантаження кодується у UTF-8 під час надсилання.

BINARY: int

Код операції двійкового кадру, 0x2. Код операції, який send() вибирає автоматично, коли data є bytes / bytearray; корисне навантаження надсилається без змін.

CLOSE: int

Код операції кадру закриття, 0x8. Надсилається close(); отримання такого кадру генерує WebSocketError («Websocket connection closed») із receive().

PING: int

Код операції ping-кадру, 0x9. Microdot автоматично відповідає на вхідні ping-повідомлення відповідним PONG всередині receive(); застосунок зазвичай їх не спостерігає.

PONG: int

Код операції pong-кадру, 0xA. Надсилається автоматично у відповідь на PING. Вхідні pong-кадри мовчки ігноруються.

Атрибути екземпляра

request: microdot.Request

Початковий microdot.Request — той самий об’єкт, який отримав обробник маршруту.

closed: bool

True після виконання close(). Перевіряйте, щоб уникнути подвійного закриття в шляхах очищення.

Методи

async receive()

Очікує та повертає наступне повідомлення від клієнта. Тип повернутого значення відповідає коду операції кадру: str для текстових кадрів, bytes для двійкових кадрів. Кадри ping автоматично отримують відповідь pong; кадри pong мовчки ігноруються; кадр close генерує WebSocketError («Websocket connection closed»).

async send(data, opcode: int | None = None)

Надсилає data клієнту. Рядки надсилаються як текстові кадри, байти — як двійкові; передайте opcode явно для перевизначення.

async close()

Надсилає кадр закриття та позначає з’єднання як закрите. Викликається автоматично, коли завершується обгортка with_websocket().

class WebSocketError

exception microdot.websocket.WebSocketError

Генерується всередині WebSocket.receive(), коли з’єднання завершується або порушується протокол. Використовуйте це у маршруті для виявлення звичайних відключень клієнта:

try:
    message = await ws.receive()
except WebSocketError:
    # client closed the connection

Декоратори на рівні модуля

microdot.websocket.with_websocket(f)

Декоратор, що перетворює маршрут на кінцеву точку WebSocket. Обробник отримує запит та об’єкт WebSocket

from microdot import Microdot
from microdot.websocket import with_websocket

app = Microdot()

@app.get('/echo')
@with_websocket
async def echo(request, ws):
    while True:
        msg = await ws.receive()
        await ws.send(msg)

Час життя обробника дорівнює часу життя з’єднання. Повернення, генерація винятку або відключення клієнта закривають WebSocket коректно.

async microdot.websocket.websocket_upgrade(request)

Допоміжна функція низькорівневого оновлення. Використовуйте її всередині маршруту, коли оновлення має відбуватися умовно — наприклад, лише після успішної перевірки авторизації:

@app.get('/private')
async def private(request):
    if not authenticate(request):
        abort(401)
    ws = await websocket_upgrade(request)
    while True:
        msg = await ws.receive()
        await ws.send(msg.upper())

Повертає оновлений WebSocket. Обробник повинен повернути microdot.Response.already_handled (або згенерувати виняток) після завершення — microdot вже перейняв управління сокетом.

Реалізація підтримує стандартні коди операцій тексту та двійкових даних, ping/pong і коректне закриття. Фрагментовані (continuation) кадри не підтримуються — кожне повідомлення надсилається як один кадр, що підходить для типових застосунків камери з невеликими повідомленнями.