microdot.sse — Server-Sent Events

Server-Sent Events (SSE) on yksinkertainen yksisuuntainen push-protokolla: asiakas avaa tavallisen HTTP-pyynnön kohteeseen Content-Type: text/event-stream, ja palvelin pitää yhteyden auki ja kirjoittaa muotoiltuja tapahtumia sitä mukaa kun niitä tapahtuu. Selain paljastaa virran JavaScript-objektina EventSource. WebSocketeihin verrattuna SSE on yksinkertaisempi, kun vain palvelin työntää; asiakas pyytää aina.

Tyypillinen kameran käyttötapa on julkaista tunnistuksia / sensorilukemia / tilapäivityksiä puhelimeen tai koontinäyttöön sitä tahtia kun niitä tapahtuu, ilman että koontinäytön tarvitsee pollata.

class SSE

class microdot.sse.SSE

Kahva, jonka reitti vastaanottaa. Välitetään käsittelijöille toisena argumenttina, kun with_sse() on käytössä.

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

Työntää yksittäisen tapahtuman asiakkaalle.

data

Tapahtuman hyötykuorma. Merkkijonot ja tavut lähetetään sellaisenaan. Dictit ja listat serialisoidaan JSON:ksi. Kaikki muu muunnetaan str()-funktiolla.

event

Valinnainen tapahtuman nimi – selaimen EventSource lähettää tämän asetettuna samannimiselle JavaScript-kuuntelijalle.

event_id

Valinnainen tapahtuman id – selain lähettää sen takaisin muodossa Last-Event-ID, jos yhteys katkeaa ja muodostuu uudelleen, mikä antaa palvelimen jatkaa siitä mihin se jäi.

retry

Uudelleenyhdistämisen viive sekunteina; selain käyttää tätä, jos yhteys katkeaa.

comment

Jos True, hyötykuorma lähetetään SSE-kommenttirivinä (selain jättää sen huomiotta). Hyödyllinen elossapitosykäyksenä, joka estää NAT-aikakatkaisuja sulkemasta muutoin jouten olevaa virtaa.

Moduulitason koristelijat

microdot.sse.with_sse(f)

Koristelija, joka muuntaa reitin SSE-päätepisteeksi. Käsittelijä vastaanottaa request-objektin ja SSE-objektin:

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)

Käsittelijän elinaika on yhtä suuri kuin virran elinaika – se suoritetaan niin kauan kuin asiakas pysyy yhteydessä. Peruutus (asiakas katkaisee yhteyden, palvelin sammuu) leviää poikkeuksena asyncio.CancelledError, jonka kehys nielee.

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

Matalan tason aloituspiste: palauttaa vastausmonikon, jonka with_sse() palauttaa konepellin alla. Hyödyllinen, kun SSE-päätepiste tarvitsee mukautettuja otsikoita tai tilakoodeja, joita koristelija ei salli:

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 ottaa parametrit (request, sse, *args, **kwargs) ja käyttää await sse.send(...) tapahtumien työntämiseen.

SSE-vastaus asettaa Content-Type: text/event-stream ja pitää yhteyden auki, kunnes event_function palaa tai asiakas katkaisee yhteyden. Käytä while True -silmukkaa, jossa on await asyncio.sleep lähetysten välissä, jotta vältät kuumalenkin (hot-looping).