microdot.sse --- 伺服器推送事件¶
伺服器推送事件(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
事件酬載。字串與位元組會原樣傳送。字典與清單會被序列化為 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 回傳或用戶端斷線為止。請使用 while True 迴圈,並在每次傳送之間加入 await asyncio.sleep,以避免熱迴圈空轉。