microdot.sse — Server-Sent Events

Server-Sent Events (SSE), basit, tek yönlü bir gönderme (push) protokolüdür: istemci Content-Type: text/event-stream‘e normal bir HTTP isteği açar ve sunucu bağlantıyı açık tutarak olaylar gerçekleştikçe biçimlendirilmiş olayları yazar. Tarayıcı, akışı bir JavaScript EventSource nesnesi olarak sunar. WebSocket’lerle karşılaştırıldığında, yalnızca sunucu gönderdiğinde SSE daha basittir; istemci her zaman istek yapar.

Tipik kamera kullanımı, tespitleri / sensör okumalarını / durum güncellemelerini, panonun yoklama yapmasına gerek kalmadan, gerçekleştikleri hızda bir telefona veya panoya yayınlamaktır.

class SSE

class microdot.sse.SSE

Rotanın aldığı tutamaç (handle). with_sse() kullanımdayken işleyicilere ikinci argüman olarak iletilir.

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

İstemciye tek bir olay gönderir.

data

Olay yükü. Dizeler ve baytlar olduğu gibi gönderilir. Dict’ler ve list’ler JSON’a serileştirilir. Diğer her şey str() ile dönüştürülür.

event

İsteğe bağlı olay adı – bu ayarlandığında tarayıcının EventSource‘u aynı adlı bir JavaScript dinleyicisine gönderir.

event_id

İsteğe bağlı olay kimliği – bağlantı kesilip yeniden bağlanırsa tarayıcı bunu Last-Event-ID olarak geri gönderir, bu da sunucunun kaldığı yerden devam etmesini sağlar.

retry

Saniye cinsinden yeniden bağlanma gecikmesi; bağlantı kesilirse tarayıcı bunu kullanır.

comment

True ise, yük bir SSE yorum satırı olarak gönderilir (tarayıcı tarafından yok sayılır). NAT zaman aşımlarının aksi takdirde boşta olan bir akışı kapatmasını engellemek için bir keep-alive nabzı olarak kullanışlıdır.

Modül düzeyindeki dekoratörler

microdot.sse.with_sse(f)

Bir rotayı bir SSE uç noktasına dönüştüren dekoratör. İşleyici, request’i ve bir SSE nesnesini alır:

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)

İşleyicinin ömrü, akışın ömrüne eşittir – istemci bağlı kaldığı sürece çalışır. İptal (istemci bağlantısını keser, sunucu kapanır) asyncio.CancelledError olarak yayılır ve bunu framework yutar.

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

Düşük seviyeli giriş noktası: with_sse()‘nin arka planda döndürdüğü yanıt demetini döndürür. Bir SSE uç noktasının, dekoratörün izin vermediği özel başlıklara veya durum kodlarına ihtiyaç duyduğunda kullanışlıdır:

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, (request, sse, *args, **kwargs) alır ve olayları göndermek için await sse.send(...) kullanır.

SSE yanıtı Content-Type: text/event-stream ayarlar ve event_function dönene veya istemci bağlantısını kesene kadar bağlantıyı açık tutar. Sıcak döngüye (hot-looping) girmemek için gönderimler arasında bir await asyncio.sleep ile bir while True döngüsü kullanın.