# -*- coding: utf-8 -*- """ 通信中间件框架 - 完整使用示例 演示:工厂创建、发布、订阅、对比三种协议 """ import asyncio import logging from adapters.dds_adapter import DDSAdapterComm from adapters.kafka_adapter import KafkaAdapterComm # ── 注册所有内置适配器 ───────────────────────────────────────────── from adapters.redis_adapter import RedisAdapterComm from uas.comm.factory import CommAdapterFactory from uas.comm.message import Message, MessagePriority CommAdapterFactory.register("redis", RedisAdapterComm) CommAdapterFactory.register("kafka", KafkaAdapterComm) CommAdapterFactory.register("dds", DDSAdapterComm) # ── 日志配置 ────────────────────────────────────────────────────── logging.basicConfig( level = logging.INFO, format = "%(asctime)s [%(levelname)s] %(name)s - %(message)s", ) logger = logging.getLogger("main") # ───────────────────────────────────────────────────────────────── # 消息处理回调 # ───────────────────────────────────────────────────────────────── async def on_aircraft_status(msg: Message): logger.info(f"🛩️ 收到飞行状态 | {msg.topic} | {msg.payload}") async def on_alert(msg: Message): logger.warning(f"🚨 告警消息 | priority={msg.priority.name} | {msg.payload}") def on_telemetry_sync(msg: Message): """同步处理器也被支持""" logger.info(f"📡 遥测数据 (sync) | {msg.payload}") # ───────────────────────────────────────────────────────────────── # 示例 1:Redis # ───────────────────────────────────────────────────────────────── async def demo_redis(): url = "redis://:mypassword@127.0.0.1:6379/0?socket_timeout=5" logger.info(f"\n{'═'*55}\n Redis 示例 url={url}\n{'═'*55}") async with CommAdapterFactory.create(url) as adapter: # 订阅 await adapter.subscribe("aircraft/status", on_aircraft_status) await adapter.subscribe("aircraft/alert", on_alert) # 发布 await adapter.publish(Message( topic = "aircraft/status", payload = {"id": "F-22", "speed": 2414, "altitude": 15000}, )) await adapter.publish(Message( topic = "aircraft/alert", payload = {"code": "E001", "msg": "发动机温度过高"}, priority = MessagePriority.URGENT, )) await asyncio.sleep(0.5) # 等待消息到达 # ───────────────────────────────────────────────────────────────── # 示例 2:Kafka # ───────────────────────────────────────────────────────────────── async def demo_kafka(): url = "kafka://broker:9092/flight-group?auto_offset_reset=earliest&acks=all" logger.info(f"\n{'═'*55}\n Kafka 示例 url={url}\n{'═'*55}") async with CommAdapterFactory.create(url) as adapter: await adapter.subscribe("telemetry", on_telemetry_sync) await adapter.publish(Message( topic = "telemetry", payload = {"aircraft": "J-20", "lat": 39.9, "lon": 116.4, "alt": 20000}, headers = {"source": "radar-01"}, )) await asyncio.sleep(1.0) # ───────────────────────────────────────────────────────────────── # 示例 3:DDS # ───────────────────────────────────────────────────────────────── async def demo_dds(): url = "dds://0@localhost:7400/rt?reliability=RELIABLE&durability=TRANSIENT_LOCAL" logger.info(f"\n{'═'*55}\n DDS 示例 url={url}\n{'═'*55}") async with CommAdapterFactory.create(url) as adapter: await adapter.subscribe("command/fire", on_alert) await adapter.publish(Message( topic = "command/fire", payload = {"weapon": "AIM-120", "target": "T001"}, priority = MessagePriority.HIGH, )) await asyncio.sleep(0.3) # ───────────────────────────────────────────────────────────────── # 示例 4:扩展新协议(MQTT) # ───────────────────────────────────────────────────────────────── async def demo_extend_mqtt(): """ 演示如何在运行时注册新协议,无需修改框架代码 只需实现 CommBaseAdapter 子类并调用 register() """ from uas.comm.base import CommBaseAdapter, MessageHandler from uas.comm.message import Message class MqttAdapter(CommBaseAdapter): """MQTT 适配器骨架(实际使用 aiomqtt 库)""" async def connect(self): self._running = True self.logger.info(f"[MQTT] 连接到 {self.config.host}:{self.config.port}") async def disconnect(self): self._running = False async def publish(self, message: Message) -> bool: self.logger.info(f"[MQTT] 发布 {message.topic}: {message.payload}") return True async def subscribe(self, topic: str, handler: MessageHandler): self._register_handler(topic, handler) self.logger.info(f"[MQTT] 订阅 {topic}") async def unsubscribe(self, topic: str): self._handlers.pop(topic, None) # 动态注册 CommAdapterFactory.register("mqtt", MqttAdapter) url = "mqtt://broker.hivemq.com:1883/aircraft?qos=1" async with CommAdapterFactory.create(url) as adapter: await adapter.subscribe("sensor/+/temp", on_telemetry_sync) await adapter.publish(Message( topic = "sensor/001/temp", payload = {"temp": 85.3}, )) logger.info(f"当前已注册协议: {CommAdapterFactory.available_schemes()}") # ───────────────────────────────────────────────────────────────── # 主入口 # ───────────────────────────────────────────────────────────────── async def main(): # 注意:Redis/Kafka 需要真实服务,DDS 在无 cyclonedds 时自动降级为模拟模式 # await demo_redis() # await demo_kafka() await demo_dds() await demo_extend_mqtt() if __name__ == "__main__": asyncio.run(main())