Skip to main content

aster/teleport/
session.rs

1//! 远程会话管理
2//!
3//! 通过 WebSocket 连接到远程会话
4
5use super::types::*;
6use super::validation::validate_session_repository;
7use std::sync::{Arc, RwLock};
8use tokio::sync::mpsc;
9
10/// 远程会话
11pub struct RemoteSession {
12    /// 配置
13    config: TeleportConfig,
14    /// 状态
15    state: Arc<RwLock<RemoteSessionState>>,
16    /// 消息发送器
17    message_tx: Option<mpsc::Sender<RemoteMessage>>,
18    /// 消息接收器
19    message_rx: Option<mpsc::Receiver<RemoteMessage>>,
20}
21
22impl RemoteSession {
23    /// 创建新的远程会话
24    pub fn new(config: TeleportConfig) -> Self {
25        let state = RemoteSessionState {
26            connection_state: ConnectionState::Disconnected,
27            sync_state: SyncState::default(),
28            config: config.clone(),
29            error: None,
30        };
31
32        Self {
33            config,
34            state: Arc::new(RwLock::new(state)),
35            message_tx: None,
36            message_rx: None,
37        }
38    }
39
40    /// 连接到远程会话
41    pub async fn connect(&mut self) -> anyhow::Result<()> {
42        // 验证仓库
43        let session_repo = self
44            .config
45            .metadata
46            .as_ref()
47            .and_then(|m| m.repo.as_deref());
48        let validation = validate_session_repository(session_repo).await;
49
50        if validation.status == RepoValidationStatus::Mismatch {
51            let error = format!(
52                "仓库不匹配: 会话仓库 {:?}, 当前仓库 {:?}",
53                validation.session_repo, validation.current_repo
54            );
55            self.set_error(&error);
56            anyhow::bail!(error);
57        }
58
59        if validation.status == RepoValidationStatus::Error {
60            let error = validation
61                .error_message
62                .unwrap_or_else(|| "仓库验证失败".to_string());
63            self.set_error(&error);
64            anyhow::bail!(error);
65        }
66
67        // 检查 ingress URL
68        let Some(_ingress_url) = &self.config.ingress_url else {
69            let error = "未提供远程服务器 URL";
70            self.set_error(error);
71            anyhow::bail!(error);
72        };
73
74        // 设置连接状态
75        self.set_connection_state(ConnectionState::Connecting);
76
77        // 创建消息通道
78        let (tx, rx) = mpsc::channel(100);
79        self.message_tx = Some(tx);
80        self.message_rx = Some(rx);
81
82        // TODO: 实际的 WebSocket 连接逻辑
83        // 这里只是框架,实际实现需要使用 tokio-tungstenite 等库
84
85        self.set_connection_state(ConnectionState::Connected);
86        Ok(())
87    }
88
89    /// 断开连接
90    pub async fn disconnect(&mut self) {
91        self.message_tx = None;
92        self.message_rx = None;
93        self.set_connection_state(ConnectionState::Disconnected);
94    }
95
96    /// 发送消息
97    pub async fn send_message(&self, message: RemoteMessage) -> anyhow::Result<()> {
98        let Some(tx) = &self.message_tx else {
99            anyhow::bail!("未连接到远程会话");
100        };
101        tx.send(message).await?;
102        Ok(())
103    }
104
105    /// 获取当前状态
106    pub fn get_state(&self) -> RemoteSessionState {
107        self.state
108            .read()
109            .map(|s| s.clone())
110            .unwrap_or_else(|_| RemoteSessionState {
111                connection_state: ConnectionState::Error,
112                sync_state: SyncState::default(),
113                config: self.config.clone(),
114                error: Some("状态读取失败".to_string()),
115            })
116    }
117
118    /// 检查是否已连接
119    pub fn is_connected(&self) -> bool {
120        self.state
121            .read()
122            .map(|s| s.connection_state == ConnectionState::Connected)
123            .unwrap_or(false)
124    }
125
126    /// 设置连接状态
127    fn set_connection_state(&self, state: ConnectionState) {
128        if let Ok(mut s) = self.state.write() {
129            s.connection_state = state;
130            if state != ConnectionState::Error {
131                s.error = None;
132            }
133        }
134    }
135
136    /// 设置错误
137    fn set_error(&self, error: &str) {
138        if let Ok(mut s) = self.state.write() {
139            s.connection_state = ConnectionState::Error;
140            s.error = Some(error.to_string());
141        }
142    }
143
144    /// 请求同步
145    pub async fn request_sync(&self) -> anyhow::Result<()> {
146        if !self.is_connected() {
147            anyhow::bail!("未连接到远程会话");
148        }
149
150        self.set_connection_state(ConnectionState::Syncing);
151
152        let sync_request = RemoteMessage {
153            message_type: RemoteMessageType::SyncRequest,
154            id: None,
155            session_id: self.config.session_id.clone(),
156            timestamp: chrono::Utc::now().to_rfc3339(),
157            payload: serde_json::json!({}),
158        };
159
160        self.send_message(sync_request).await?;
161        Ok(())
162    }
163}
164
165/// 创建远程会话
166pub fn create_remote_session(config: TeleportConfig) -> RemoteSession {
167    RemoteSession::new(config)
168}