base_agent/uas/comm/main.py

165 lines
7.5 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
# -*- 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}")
# ─────────────────────────────────────────────────────────────────
# 示例 1Redis
# ─────────────────────────────────────────────────────────────────
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) # 等待消息到达
# ─────────────────────────────────────────────────────────────────
# 示例 2Kafka
# ─────────────────────────────────────────────────────────────────
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)
# ─────────────────────────────────────────────────────────────────
# 示例 3DDS
# ─────────────────────────────────────────────────────────────────
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())