Skip to main content

rpi_server/
transport.rs

1use async_trait::async_trait;
2use serde_json::Value;
3use std::sync::Arc;
4use std::time::{Duration, Instant};
5use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
6use tokio::net::{TcpListener, TcpStream};
7use tokio::sync::{Mutex, RwLock};
8
9/// 传输层 trait - 抽象底层协议
10#[async_trait]
11pub trait Transport: Send + Sync + 'static {
12    type Connection: Connection;
13
14    /// 启动监听(服务端用)
15    async fn listen(&self, addr: &str) -> Result<(), String>;
16
17    /// 接受新连接(服务端用)
18    async fn accept(&self) -> Result<Self::Connection, String>;
19
20    /// 连接到远端(客户端用)
21    async fn connect(&self, addr: &str) -> Result<Self::Connection, String>;
22
23    /// 停止监听
24    async fn shutdown(&self) -> Result<(), String>;
25}
26
27/// 单个连接 trait - 抽象消息收发
28#[async_trait]
29pub trait Connection: Send + 'static {
30    /// 发送 JSON 消息
31    async fn send(&mut self, msg: Value) -> Result<(), String>;
32
33    /// 接收 JSON 消息(返回 None 表示连接关闭)
34    async fn recv(&mut self) -> Result<Option<Value>, String>;
35
36    /// 连接 ID
37    fn id(&self) -> &str;
38
39    /// 关闭连接
40    async fn close(&mut self) -> Result<(), String>;
41}
42
43/// 连接状态
44#[derive(Debug, Clone)]
45pub struct ConnectionStatus {
46    pub connected: bool,
47    pub reconnect_attempts: u32,
48    pub last_heartbeat: Option<Instant>,
49    pub latency_ms: u64,
50    pub messages_sent: u64,
51    pub messages_received: u64,
52}
53
54/// 连接管理器 - 封装重试、心跳、状态
55pub struct ManagedConnection<T: Transport> {
56    transport: Arc<T>,
57    max_retries: u32,
58    heartbeat_interval: Duration,
59    retry_delay: Duration,
60    status: Arc<RwLock<ConnectionStatus>>,
61    connection: Arc<Mutex<Option<T::Connection>>>,
62}
63
64impl<T: Transport> ManagedConnection<T> {
65    pub fn new(transport: Arc<T>) -> Self {
66        Self {
67            transport,
68            max_retries: 10,
69            heartbeat_interval: Duration::from_secs(30),
70            retry_delay: Duration::from_secs(1),
71            status: Arc::new(RwLock::new(ConnectionStatus {
72                connected: false,
73                reconnect_attempts: 0,
74                last_heartbeat: None,
75                latency_ms: 0,
76                messages_sent: 0,
77                messages_received: 0,
78            })),
79            connection: Arc::new(Mutex::new(None)),
80        }
81    }
82
83    /// 带重试的连接(客户端用)
84    pub async fn connect_with_retry(&self, addr: &str) -> Result<(), String> {
85        for attempt in 1..=self.max_retries {
86            {
87                let mut status = self.status.write().await;
88                status.reconnect_attempts = attempt;
89            }
90
91            match self.transport.connect(addr).await {
92                Ok(conn) => {
93                    *self.connection.lock().await = Some(conn);
94                    let mut status = self.status.write().await;
95                    status.connected = true;
96                    status.reconnect_attempts = 0;
97                    return Ok(());
98                }
99                Err(e) if attempt < self.max_retries => {
100                    eprintln!(
101                        "connect failed (attempt {}/{}): {}, retrying...",
102                        attempt, self.max_retries, e
103                    );
104                    tokio::time::sleep(self.retry_delay * attempt).await;
105                }
106                Err(e) => {
107                    let mut status = self.status.write().await;
108                    status.connected = false;
109                    return Err(format!(
110                        "connect failed after {} attempts: {}",
111                        self.max_retries, e
112                    ));
113                }
114            }
115        }
116        unreachable!()
117    }
118
119    /// 发送消息
120    pub async fn send(&self, msg: Value) -> Result<(), String> {
121        let mut conn_guard = self.connection.lock().await;
122        let conn = conn_guard
123            .as_mut()
124            .ok_or_else(|| "not connected".to_string())?;
125
126        conn.send(msg).await?;
127
128        let mut status = self.status.write().await;
129        status.messages_sent += 1;
130
131        Ok(())
132    }
133
134    /// 接收消息
135    pub async fn recv(&self) -> Result<Option<Value>, String> {
136        let mut conn_guard = self.connection.lock().await;
137        let conn = conn_guard
138            .as_mut()
139            .ok_or_else(|| "not connected".to_string())?;
140
141        let result = conn.recv().await?;
142
143        if result.is_some() {
144            let mut status = self.status.write().await;
145            status.messages_received += 1;
146        } else {
147            // 连接关闭
148            let mut status = self.status.write().await;
149            status.connected = false;
150        }
151
152        Ok(result)
153    }
154
155    /// 启动心跳(在独立 task 中运行)
156    pub async fn start_heartbeat(&self) -> Result<(), String> {
157        let mut interval = tokio::time::interval(self.heartbeat_interval);
158
159        loop {
160            interval.tick().await;
161
162            let ping = serde_json::json!({
163                "type": "ping",
164                "timestamp": std::time::SystemTime::now()
165                    .duration_since(std::time::UNIX_EPOCH)
166                    .unwrap()
167                    .as_millis()
168            });
169
170            let start = Instant::now();
171            self.send(ping).await?;
172
173            // 等待 pong(带超时)
174            match tokio::time::timeout(Duration::from_secs(5), self.recv()).await {
175                Ok(Ok(Some(msg))) if msg["type"] == "pong" => {
176                    let latency = start.elapsed().as_millis() as u64;
177                    let mut status = self.status.write().await;
178                    status.latency_ms = latency;
179                    status.last_heartbeat = Some(Instant::now());
180                }
181                Ok(Ok(None)) => {
182                    let mut status = self.status.write().await;
183                    status.connected = false;
184                    return Err("connection closed during heartbeat".into());
185                }
186                Ok(Err(e)) => {
187                    let mut status = self.status.write().await;
188                    status.connected = false;
189                    return Err(format!("heartbeat error: {}", e));
190                }
191                Err(_) => {
192                    let mut status = self.status.write().await;
193                    status.connected = false;
194                    return Err("heartbeat timeout".into());
195                }
196                _ => {}
197            }
198        }
199    }
200
201    /// 获取当前状态
202    pub async fn status(&self) -> ConnectionStatus {
203        self.status.read().await.clone()
204    }
205
206    /// 关闭连接
207    pub async fn close(&self) -> Result<(), String> {
208        let mut conn_guard = self.connection.lock().await;
209        if let Some(mut conn) = conn_guard.take() {
210            conn.close().await?;
211        }
212        let mut status = self.status.write().await;
213        status.connected = false;
214        Ok(())
215    }
216}
217
218impl<T: Transport> Clone for ManagedConnection<T> {
219    fn clone(&self) -> Self {
220        Self {
221            transport: Arc::clone(&self.transport),
222            max_retries: self.max_retries,
223            heartbeat_interval: self.heartbeat_interval,
224            retry_delay: self.retry_delay,
225            status: Arc::clone(&self.status),
226            connection: Arc::clone(&self.connection),
227        }
228    }
229}
230
231// ── TCP 实现 ──────────────────────────────────────────────────────────────────
232
233pub struct TcpTransport {
234    listener: Mutex<Option<TcpListener>>,
235}
236
237impl TcpTransport {
238    pub fn new() -> Self {
239        Self {
240            listener: Mutex::new(None),
241        }
242    }
243}
244
245#[async_trait]
246impl Transport for TcpTransport {
247    type Connection = TcpConnection;
248
249    async fn listen(&self, addr: &str) -> Result<(), String> {
250        let listener = TcpListener::bind(addr)
251            .await
252            .map_err(|e| format!("bind failed: {e}"))?;
253        *self.listener.lock().await = Some(listener);
254        Ok(())
255    }
256
257    async fn accept(&self) -> Result<TcpConnection, String> {
258        let listener = self.listener.lock().await;
259        let listener = listener.as_ref().ok_or("not listening")?;
260
261        let (stream, addr) = listener
262            .accept()
263            .await
264            .map_err(|e| format!("accept failed: {e}"))?;
265
266        Ok(TcpConnection::new(stream, format!("tcp-{addr}")))
267    }
268
269    async fn connect(&self, addr: &str) -> Result<TcpConnection, String> {
270        let stream = TcpStream::connect(addr)
271            .await
272            .map_err(|e| format!("connect failed: {e}"))?;
273
274        Ok(TcpConnection::new(stream, format!("tcp-client-{addr}")))
275    }
276
277    async fn shutdown(&self) -> Result<(), String> {
278        *self.listener.lock().await = None;
279        Ok(())
280    }
281}
282
283pub struct TcpConnection {
284    reader: BufReader<tokio::net::tcp::OwnedReadHalf>,
285    writer: tokio::net::tcp::OwnedWriteHalf,
286    id: String,
287}
288
289impl TcpConnection {
290    pub fn new(stream: TcpStream, id: String) -> Self {
291        let (reader, writer) = stream.into_split();
292        Self {
293            reader: BufReader::new(reader),
294            writer,
295            id,
296        }
297    }
298}
299
300#[async_trait]
301impl Connection for TcpConnection {
302    async fn send(&mut self, msg: Value) -> Result<(), String> {
303        let mut line = serde_json::to_string(&msg).map_err(|e| format!("serialize failed: {e}"))?;
304        line.push('\n');
305
306        self.writer
307            .write_all(line.as_bytes())
308            .await
309            .map_err(|e| format!("write failed: {e}"))?;
310
311        Ok(())
312    }
313
314    async fn recv(&mut self) -> Result<Option<Value>, String> {
315        let mut line = String::new();
316
317        match self.reader.read_line(&mut line).await {
318            Ok(0) => Ok(None), // EOF
319            Ok(_) => {
320                let msg =
321                    serde_json::from_str(line.trim()).map_err(|e| format!("parse failed: {e}"))?;
322                Ok(Some(msg))
323            }
324            Err(e) => Err(format!("read failed: {e}")),
325        }
326    }
327
328    fn id(&self) -> &str {
329        &self.id
330    }
331
332    async fn close(&mut self) -> Result<(), String> {
333        self.writer
334            .shutdown()
335            .await
336            .map_err(|e| format!("close failed: {e}"))
337    }
338}