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()が使用されている場合、第2引数としてハンドラに渡されます。- async send(data, event: str | None = None, event_id: str | None = None, retry: int | None = None, comment: bool = False)¶
単一のイベントをクライアントにプッシュします。
- data
イベントのペイロードです。文字列とバイトはそのまま送信されます。辞書とリストはJSONにシリアライズされます。それ以外のものは
str()で変換されます。- event
オプションのイベント名です -- これが設定されると、ブラウザの
EventSourceは同じ名前のJavaScriptリスナーにディスパッチします。- event_id
オプションのイベントIDです -- 接続が切断されて再接続された場合、ブラウザはこれを
Last-Event-IDとして返送し、サーバーが中断したところから再開できるようにします。- retry
秒単位の再接続遅延です。接続が切断された場合にブラウザがこれを使用します。
- comment
Trueの場合、ペイロードはSSEのコメント行として送信されます(ブラウザからは無視されます)。NATのタイムアウトがアイドル状態のストリームを閉じるのを防ぐためのキープアライブのハートビートとして便利です。
モジュールレベルのデコレータ¶
- 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 が戻るかクライアントが切断するまで接続を開いたままにします。ホットループを避けるため、送信の間に await asyncio.sleep を挟んだ while True ループを使用してください。