Files
sanguo_moziplus_v2/src/api/sse_routes.py
T
2026-05-17 06:29:41 +08:00

53 lines
1.3 KiB
Python

"""SSE 推送路由"""
from __future__ import annotations
import asyncio
from typing import Optional
from fastapi import APIRouter, Query, Request
from fastapi.responses import StreamingResponse
from src.daemon.sse import SSEBroker
router = APIRouter(prefix="/api/events", tags=["sse"])
_broker: Optional[SSEBroker] = None
def get_broker() -> SSEBroker:
global _broker
if _broker is None:
_broker = SSEBroker()
return _broker
def set_broker(broker: SSEBroker) -> None:
global _broker
_broker = broker
@router.get("")
async def event_stream(
request: Request,
project: Optional[str] = Query(None, description="Filter by project ID"),
):
"""SSE 端点 — 实时推送黑板事件"""
broker = get_broker()
async def generate():
cid, queue = broker.subscribe()
try:
while True:
if await request.is_disconnected():
break
try:
event = await asyncio.wait_for(queue.get(), timeout=30.0)
yield event.to_sse()
except asyncio.TimeoutError:
yield ": heartbeat\n\n"
finally:
broker.unsubscribe(cid)
return StreamingResponse(generate(), media_type="text/event-stream")