Coverage for src\core\communication.py: 0%
80 statements
« prev ^ index » next coverage.py v7.3.4, created at 2026-04-21 14:54 +0800
« prev ^ index » next coverage.py v7.3.4, created at 2026-04-21 14:54 +0800
1"""
2Communication Module - 通信模块
4提供设备间的消息传递功能
5"""
7import asyncio
8import json
9import logging
10from typing import Dict, Optional, Callable, Any
11from dataclasses import dataclass
12from enum import Enum
14logger = logging.getLogger(__name__)
17class MessageType(str, Enum):
18 """消息类型"""
19 TEXT = "text"
20 SYNC = "sync"
21 COMMAND = "command"
22 RESPONSE = "response"
23 HEARTBEAT = "heartbeat"
26@dataclass
27class Message:
28 """消息"""
29 msg_id: str
30 msg_type: MessageType
31 sender: str
32 receiver: str
33 content: Any
34 timestamp: float
37class Communication:
38 """
39 通信管理器
41 负责设备间的消息发送和接收
42 """
44 def __init__(self, device_id: str, config=None):
45 self.device_id = device_id
46 self.config = config
47 self.connections: Dict[str, asyncio.StreamWriter] = {}
48 self.message_handlers: Dict[MessageType, Callable] = {}
49 self._running = False
50 self._heartbeat_task: Optional[asyncio.Task] = None
52 async def connect_to(self, peer_id: str, host: str = "localhost", port: int = 8765) -> bool:
53 """
54 连接到对等节点
56 Args:
57 peer_id: 对等节点ID
58 host: 主机地址
59 port: 端口
61 Returns:
62 bool: 连接是否成功
63 """
64 try:
65 reader, writer = await asyncio.open_connection(host, port)
66 self.connections[peer_id] = writer
67 logger.info(f"已连接到 {peer_id}")
68 return True
69 except Exception as e:
70 logger.error(f"连接失败: {e}")
71 return False
73 async def disconnect(self):
74 """断开所有连接"""
75 self._running = False
77 for peer_id, writer in self.connections.items():
78 writer.close()
79 await writer.wait_closed()
81 self.connections.clear()
82 logger.info("已断开所有连接")
84 async def disconnect_peer(self, peer_id: str):
85 """断开指定对等节点的连接"""
86 if peer_id in self.connections:
87 writer = self.connections[peer_id]
88 writer.close()
89 await writer.wait_closed()
90 del self.connections[peer_id]
91 logger.info(f"已断开与 {peer_id} 的连接")
93 async def send_message(self, peer_id: str, content: Any,
94 msg_type: MessageType = MessageType.TEXT) -> bool:
95 """
96 发送消息
98 Args:
99 peer_id: 对等节点ID
100 content: 消息内容
101 msg_type: 消息类型
103 Returns:
104 bool: 发送是否成功
105 """
106 if peer_id not in self.connections:
107 logger.warning(f"未连接到 {peer_id}")
108 return False
110 try:
111 message = Message(
112 msg_id=f"{self.device_id}_{asyncio.get_event_loop().time()}",
113 msg_type=msg_type,
114 sender=self.device_id,
115 receiver=peer_id,
116 content=content,
117 timestamp=asyncio.get_event_loop().time()
118 )
120 data = json.dumps({
121 "msg_id": message.msg_id,
122 "msg_type": message.msg_type.value,
123 "sender": message.sender,
124 "receiver": message.receiver,
125 "content": message.content,
126 "timestamp": message.timestamp
127 })
129 writer = self.connections[peer_id]
130 writer.write(data.encode())
131 await writer.drain()
132 return True
134 except Exception as e:
135 logger.error(f"发送消息失败: {e}")
136 return False
138 def register_handler(self, msg_type: MessageType, handler: Callable):
139 """注册消息处理器"""
140 self.message_handlers[msg_type] = handler
142 async def start_heartbeat(self, interval: int = 30):
143 """启动心跳"""
144 self._running = True
146 async def heartbeat():
147 while self._running:
148 await asyncio.sleep(interval)
149 for peer_id in self.connections:
150 await self.send_message(peer_id, {}, MessageType.HEARTBEAT)
152 self._heartbeat_task = asyncio.create_task(heartbeat())
154 def get_connected_peers(self) -> list:
155 """获取已连接的节点列表"""
156 return list(self.connections.keys())
158 def is_connected(self, peer_id: str) -> bool:
159 """检查是否连接到指定节点"""
160 return peer_id in self.connections