microdot.websocket — suporte a WebSocket

WebSockets são uma conexão persistente bidirecional sobre HTTP – após um handshake de upgrade, cliente e servidor enviam e recebem mensagens enquadradas no mesmo socket. Use-os quando a câmera e uma aplicação no lado do navegador precisarem de tráfego full-duplex que o SSE (push unidirecional) e o polling HTTP simples não conseguem oferecer de forma barata.

class WebSocket

class microdot.websocket.WebSocket(request)

O handle que a rota recebe. Passado para os handlers como segundo argumento quando with_websocket() está em uso; não o construa diretamente.

Atributos de classe

max_message_length: int

Tamanho máximo de payload que receive() aceitará. Mensagens maiores que isso levantam WebSocketError e fecham a conexão. 0 desabilita a verificação (esteja ciente de ataques de exaustão de memória se definir isso). -1 (padrão) usa Request.max_body_length.

CONT: int

Opcode de quadro de continuação, 0x0. Marca um quadro que dá continuidade ao payload do quadro anterior da mesma mensagem. O Microdot não gera quadros de continuação por conta própria (cada mensagem sai como um único quadro) e os rejeita no recebimento, mas a constante é exposta para aplicações que implementam enquadramento personalizado.

TEXT: int

Opcode de quadro de texto, 0x1. O opcode que send() escolhe automaticamente quando data é uma str; o payload é codificado em UTF-8 na saída.

BINARY: int

Opcode de quadro binário, 0x2. O opcode que send() escolhe automaticamente quando data é bytes / bytearray; o payload é enviado literalmente.

CLOSE: int

Opcode de quadro de fechamento, 0x8. Enviado por close(); receber um levanta WebSocketError (“Websocket connection closed”) a partir de receive().

PING: int

Opcode de quadro ping, 0x9. O Microdot responde aos pings recebidos automaticamente com um PONG correspondente dentro de receive(); normalmente a aplicação não os observa.

PONG: int

Opcode de quadro pong, 0xA. Enviado automaticamente em resposta a um PING. Pongs recebidos são descartados silenciosamente.

Atributos de instância

request: microdot.Request

O microdot.Request de origem – o mesmo objeto que o handler de rota recebeu.

closed: bool

True após close() ter sido executado. Inspecione para evitar fechamento duplo em caminhos de limpeza.

Métodos

async receive()

Aguarda e retorna a próxima mensagem do cliente. O tipo de retorno corresponde ao opcode do quadro: str para quadros de texto, bytes para quadros binários. Quadros ping são respondidos automaticamente com um pong; quadros pong são descartados silenciosamente; um quadro close levanta WebSocketError (“Websocket connection closed”).

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

Envia data para o cliente. Strings são enviadas como quadros de texto, bytes como quadros binários; passe opcode explicitamente para sobrepor.

async close()

Envia um quadro de fechamento e marca a conexão como fechada. Chamado automaticamente quando o wrapper de with_websocket() é encerrado.

class WebSocketError

exception microdot.websocket.WebSocketError

Levantada dentro de WebSocket.receive() quando a conexão termina ou o protocolo é violado. Use isso em uma rota para detectar desconexões normais do cliente:

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

Decoradores em nível de módulo

microdot.websocket.with_websocket(f)

Decorador que transforma uma rota em um endpoint WebSocket. O handler recebe a requisição e um objeto 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)

O tempo de vida do handler é igual ao tempo de vida da conexão. Retornar, levantar uma exceção ou uma desconexão do cliente fecha o WebSocket de forma limpa.

async microdot.websocket.websocket_upgrade(request)

Auxiliar de upgrade de baixo nível. Use isso dentro de uma rota quando o upgrade deve acontecer condicionalmente – por exemplo, apenas após uma verificação de autorização ser aprovada:

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

Retorna o WebSocket com upgrade realizado. O handler deve retornar microdot.Response.already_handled (ou levantar uma exceção) ao terminar – o microdot já assumiu o controle do socket.

A implementação suporta os opcodes padrão de texto e binário, ping / pong e um fechamento limpo. Quadros fragmentados (de continuação) não são suportados – cada mensagem é enviada como um único quadro, o que é apropriado para as típicas aplicações de câmera com mensagens pequenas.