microdot.websocket — supporto WebSocket

I WebSocket sono una connessione persistente bidirezionale su HTTP: dopo un handshake di upgrade, client e server inviano e ricevono messaggi suddivisi in frame sullo stesso socket. Usali quando la camera e un’applicazione lato browser hanno bisogno di traffico full-duplex che SSE (push unidirezionale) e il semplice polling HTTP non possono fornire in modo economico.

class WebSocket

class microdot.websocket.WebSocket(request)

L’handle che la route riceve. Viene passato agli handler come secondo argomento quando si utilizza with_websocket(); non costruirlo direttamente.

Attributi di classe

max_message_length: int

Dimensione massima del payload che receive() accetterà. I messaggi più grandi di questa sollevano WebSocketError e chiudono la connessione. 0 disabilita il controllo (attenzione agli attacchi di esaurimento della memoria se imposti questo valore). -1 (predefinito) usa Request.max_body_length.

CONT: int

Opcode del frame di continuazione, 0x0. Contrassegna un frame che continua il payload del frame precedente per lo stesso messaggio. Microdot non genera frame di continuazione di per sé (ogni messaggio viene inviato come un singolo frame) e li rifiuta in ricezione, ma la costante è esposta per le applicazioni che implementano un framing personalizzato.

TEXT: int

Opcode del frame di testo, 0x1. L’opcode che send() sceglie automaticamente quando data è una str; il payload viene codificato in UTF-8 in uscita.

BINARY: int

Opcode del frame binario, 0x2. L’opcode che send() sceglie automaticamente quando data è bytes / bytearray; il payload viene inviato verbatim.

CLOSE: int

Opcode del frame di chiusura, 0x8. Inviato da close(); riceverne uno solleva WebSocketError («Websocket connection closed») da receive().

PING: int

Opcode del frame ping, 0x9. Microdot risponde ai ping in arrivo con un PONG corrispondente automaticamente all’interno di receive(); normalmente l’applicazione non li osserva.

PONG: int

Opcode del frame pong, 0xA. Inviato automaticamente in risposta a un PING. I pong in arrivo vengono scartati silenziosamente.

Attributi di istanza

request: microdot.Request

La microdot.Request di origine: lo stesso oggetto ricevuto dall’handler della route.

closed: bool

True una volta che close() è stata eseguita. Ispezionalo per evitare doppie chiusure nei percorsi di cleanup.

Metodi

async receive()

Attende e restituisce il messaggio successivo dal client. Il tipo restituito corrisponde all’opcode del frame: str per i frame di testo, bytes per i frame binari. I frame ping ricevono automaticamente una risposta con un pong; i frame pong vengono scartati silenziosamente; un frame close solleva WebSocketError («Websocket connection closed»).

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

Invia data al client. Le stringhe vengono inviate come frame di testo, i byte come frame binari; passa opcode esplicitamente per sovrascrivere il comportamento.

async close()

Invia un frame di chiusura e contrassegna la connessione come chiusa. Chiamato automaticamente quando il wrapper di with_websocket() termina.

class WebSocketError

exception microdot.websocket.WebSocketError

Sollevata all’interno di WebSocket.receive() quando la connessione termina o il protocollo viene violato. Usala in una route per rilevare le normali disconnessioni del client:

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

Decoratori a livello di modulo

microdot.websocket.with_websocket(f)

Decoratore che trasforma una route in un endpoint WebSocket. L’handler riceve la richiesta e un oggetto 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)

La durata dell’handler è pari alla durata della connessione. Il ritorno, il sollevamento di un’eccezione o una disconnessione del client chiudono il WebSocket in modo pulito.

async microdot.websocket.websocket_upgrade(request)

Helper di upgrade di basso livello. Usalo all’interno di una route quando l’upgrade deve avvenire in modo condizionale, ad esempio solo dopo che un controllo di autorizzazione ha esito positivo:

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

Restituisce il WebSocket aggiornato. L’handler deve restituire microdot.Response.already_handled (o sollevare un’eccezione) una volta terminato: microdot ha già preso il controllo del socket.

L’implementazione supporta gli opcode standard di testo e binari, ping / pong e una chiusura pulita. I frame frammentati (di continuazione) non sono supportati: ogni messaggio viene inviato come un singolo frame, il che è appropriato per le tipiche applicazioni della camera con messaggi di piccole dimensioni.