microdot.sse — Server-Sent Events

Server-Sent Events (SSE) este un protocol simplu de împingere (push) unidirecțional: clientul deschide o cerere HTTP normală către Content-Type: text/event-stream, iar serverul menține conexiunea deschisă și scrie evenimente formatate pe măsură ce acestea apar. Browserul expune fluxul ca un obiect JavaScript EventSource. Comparat cu WebSockets, SSE este mai simplu atunci când doar serverul împinge; clientul solicită întotdeauna.

Utilizarea tipică pe cameră este publicarea detectărilor / citirilor de senzori / actualizărilor de stare către un telefon sau un tablou de bord la rata la care acestea apar, fără ca tabloul de bord să fie nevoit să interogheze.

class SSE

class microdot.sse.SSE

Mânerul pe care îl primește ruta. Transmis gestionarilor drept al doilea argument când with_sse() este în uz.

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

Împinge un singur eveniment către client.

data

Sarcina utilă a evenimentului. Șirurile și octeții sunt trimiși ca atare. Dict-urile și listele sunt serializate în JSON. Orice altceva este convertit prin str().

event

Nume opțional de eveniment – EventSource al browserului expediază către un ascultător JavaScript cu același nume când acesta este setat.

event_id

Id opțional de eveniment – browserul îl trimite înapoi ca Last-Event-ID dacă conexiunea cade și se reconectează, ceea ce permite serverului să reia de unde a rămas.

retry

Întârzierea de reconectare în secunde; browserul o folosește dacă conexiunea cade.

comment

Dacă este True, sarcina utilă este trimisă ca o linie de comentariu SSE (ignorată de browser). Utilă ca puls de menținere a conexiunii (keep-alive) pentru a împiedica expirările NAT să închidă un flux altfel inactiv.

Decoratoare la nivel de modul

microdot.sse.with_sse(f)

Decorator care transformă o rută într-un punct final SSE. Gestionarul primește cererea și un obiect 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)

Durata de viață a gestionarului este egală cu durata de viață a fluxului – rulează atât timp cât clientul rămâne conectat. Anularea (clientul se deconectează, serverul se oprește) se propagă ca asyncio.CancelledError, pe care framework-ul o înghite.

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

Punct de intrare de nivel jos: returnează tuplul de răspuns pe care with_sse() îl returnează în culise. Util când un punct final SSE are nevoie de antete sau coduri de stare personalizate pe care decoratorul nu le permite:

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 primește (request, sse, *args, **kwargs) și folosește await sse.send(...) pentru a împinge evenimente.

Răspunsul SSE setează Content-Type: text/event-stream și menține conexiunea deschisă până când event_function returnează sau clientul se deconectează. Folosiți o buclă while True cu un await asyncio.sleep între trimiteri pentru a evita bucla intensă (hot-looping).