4d4d38fe0f
迁自 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/知识库/语音/视觉重模块延后全量迁入。
45 lines
1.0 KiB
Python
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()
|