microdot.sse — Server-Sent Events

Server-Sent Events (SSE) je jednoduchý jednosměrný push protokol: klient otevře běžný HTTP požadavek na Content-Type: text/event-stream a server udržuje spojení otevřené a zapisuje naformátované události tak, jak nastávají. Prohlížeč zpřístupňuje stream jako objekt JavaScriptu EventSource. Ve srovnání s WebSockety je SSE jednodušší, když pushuje pouze server; klient vždy žádá.

Typické použití na kameře je publikování detekcí / odečtů ze senzorů / aktualizací stavu na telefon nebo dashboard rychlostí, jakou nastávají, aniž by dashboard musel dotazovat.

class SSE

class microdot.sse.SSE

Handle, který routa obdrží. Předává se obslužným rutinám jako druhý argument, když se používá with_sse().

async send(data, event: str | None = None, event_id: str | None = None, retry: int | None = None, comment: bool = False)

Odešle klientovi jedinou událost.

data

Payload události. Řetězce a bajty se odesílají tak, jak jsou. Dicty a listy se serializují do JSON. Cokoli jiného se převede pomocí str().

event

Volitelný název události – EventSource prohlížeče doručí událost JavaScriptovému posluchači stejného názvu, pokud je nastaven.

event_id

Volitelné id události – prohlížeč jej odešle zpět jako Last-Event-ID, pokud se spojení přeruší a znovu naváže, což serveru umožní pokračovat tam, kde skončil.

retry

Prodleva pro opětovné připojení v sekundách; prohlížeč ji použije, pokud se spojení přeruší.

comment

Pokud True, payload se odešle jako řádek komentáře SSE (prohlížeč jej ignoruje). Užitečné jako keep-alive heartbeat, který zabrání NAT timeoutům v uzavření jinak nečinného streamu.

Dekorátory na úrovni modulu

microdot.sse.with_sse(f)

Dekorátor, který promění routu v SSE koncový bod. Obslužná rutina obdrží požadavek a objekt SSE

from microdot import Microdot
from microdot.sse import with_sse

app = Microdot()

@app.get('/events')
@with_sse
async def events(request, sse):
    import asyncio
    while True:
        await sse.send({'temp': read_sensor()}, event='reading')
        await asyncio.sleep(1)

Životnost obslužné rutiny se rovná životnosti streamu – běží tak dlouho, dokud zůstává klient připojen. Zrušení (klient se odpojí, server se vypne) se šíří jako asyncio.CancelledError, kterou framework spolkne.

microdot.sse.sse_response(request, event_function, *args, **kwargs)

Nízkoúrovňový vstupní bod: vrací n-tici odpovědi, kterou with_sse() vrací pod kapotou. Užitečné, když SSE koncový bod potřebuje vlastní hlavičky nebo stavové kódy, které dekorátor neumožňuje:

from microdot.sse import sse_response

@app.get('/events')
async def events(request):
    if not request.g.current_user:
        return 401
    async def emit(req, sse):
        await sse.send('hello')
    return sse_response(request, emit)

event_function přebírá (request, sse, *args, **kwargs) a používá await sse.send(...) k odesílání událostí.

Odpověď SSE nastaví Content-Type: text/event-stream a udržuje spojení otevřené, dokud se event_function nevrátí nebo se klient neodpojí. Použijte smyčku while True s await asyncio.sleep mezi odesíláními, abyste se vyhnuli horké smyčce.