Files
server-core/app/park/event_bus.py
T
Pine 4d4d38fe0f feat(park): 园区子应用 app/park 骨架迁入 — dispatcher /park 前缀分流
迁自 park-desktop/backend/app:config(数据目录→serverdata/park)/storage/sim_engine/
mqtt/event_bus + 精简 routers(health/settings/config/dashboard/park/companies/display/
events) + app.py 子应用(lifespan 起 MQTT hub+tick 线程, include_router prefix=/park)。
dispatcher.py 增 ROUTE_PARK_PREFIX + _prefix_app,与 app.training(/api)、app.main 分流。
pyproject 增 paho-mqtt(MQTT 必需)。AI/知识库/语音/视觉重模块延后全量迁入。
2026-08-24 16:57:27 +08:00

45 lines
1.0 KiB
Python

# -*- coding: utf-8 -*-
"""SSE 事件总线 —— 兼容旧通道(前端 MQTT 不可用时回退)
所有 MQTT 控制指令同时推送到 SSE /api/events
"""
import asyncio
import json
class EventBus:
def __init__(self):
self._queues = set()
self._loop = None
def set_loop(self, loop):
self._loop = loop
def subscribe(self):
q = asyncio.Queue(maxsize=256)
self._queues.add(q)
return q
def unsubscribe(self, q):
self._queues.discard(q)
def emit(self, payload: dict):
"""线程安全:从任意线程广播事件"""
if not self._loop:
return
try:
asyncio.run_coroutine_threadsafe(self._emit(payload), self._loop)
except Exception: # noqa: BLE001
pass
async def _emit(self, payload):
data = json.dumps(payload, ensure_ascii=False)
for q in list(self._queues):
try:
q.put_nowait(data)
except asyncio.QueueFull:
pass
bus = EventBus()