microdot.sse — Server-Sent Events

Server-Sent Events(SSE)는 간단한 단방향 푸시 프로토콜입니다: 클라이언트가 Content-Type: text/event-stream으로 일반 HTTP 요청을 열면, 서버는 연결을 열어 둔 채로 이벤트가 발생할 때마다 포맷된 이벤트를 작성합니다. 브라우저는 이 스트림을 JavaScript EventSource 객체로 노출합니다. WebSocket과 비교하면, 서버만 푸시할 때 SSE가 더 간단합니다. 클라이언트는 항상 요청하는 쪽입니다.

전형적인 카메라 사용 사례는 검출 결과 / 센서 판독값 / 상태 업데이트를 대시보드가 폴링할 필요 없이 발생하는 속도에 맞춰 휴대폰이나 대시보드에 게시하는 것입니다.

class SSE

class microdot.sse.SSE

라우트가 받는 핸들입니다. with_sse()를 사용 중일 때 두 번째 인자로 핸들러에 전달됩니다.

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

단일 이벤트를 클라이언트에 푸시합니다.

data

이벤트 페이로드입니다. 문자열과 바이트는 그대로 전송됩니다. dict와 list는 JSON으로 직렬화됩니다. 그 외의 것은 str()로 변환됩니다.

event

선택적 이벤트 이름 – 이것이 설정되면 브라우저의 EventSource는 같은 이름의 JavaScript 리스너로 디스패치합니다.

event_id

선택적 이벤트 id – 연결이 끊겼다가 재연결되면 브라우저가 이것을 Last-Event-ID로 다시 보내므로, 서버가 중단된 지점부터 재개할 수 있습니다.

retry

재연결 지연 시간(초)입니다. 연결이 끊기면 브라우저가 이것을 사용합니다.

comment

True이면 페이로드가 SSE 주석 라인으로 전송됩니다(브라우저는 무시함). 그 외에는 유휴 상태인 스트림을 NAT 타임아웃이 닫지 못하도록 막는 킵얼라이브(keep-alive) 하트비트로 유용합니다.

모듈 수준 데코레이터

microdot.sse.with_sse(f)

라우트를 SSE 엔드포인트로 바꾸는 데코레이터입니다. 핸들러는 요청과 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)

핸들러의 수명은 스트림의 수명과 같습니다 – 클라이언트가 연결을 유지하는 동안 계속 실행됩니다. 취소(클라이언트 연결 끊김, 서버 종료)는 asyncio.CancelledError로 전파되며, 프레임워크가 이를 삼킵니다.

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

저수준 진입점: with_sse()가 내부에서 반환하는 응답 튜플을 반환합니다. SSE 엔드포인트가 데코레이터가 허용하지 않는 사용자 정의 헤더나 상태 코드를 필요로 할 때 유용합니다:

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)를 받으며 await sse.send(...)를 사용하여 이벤트를 푸시합니다.

SSE 응답은 Content-Type: text/event-stream을 설정하고 event_function이 반환하거나 클라이언트가 연결을 끊을 때까지 연결을 열어 둡니다. 핫 루핑(hot-looping)을 피하려면 전송 사이에 await asyncio.sleep을 둔 while True 루프를 사용하십시오.