aster/teleport/
session.rs1use super::types::*;
6use super::validation::validate_session_repository;
7use std::sync::{Arc, RwLock};
8use tokio::sync::mpsc;
9
10pub struct RemoteSession {
12 config: TeleportConfig,
14 state: Arc<RwLock<RemoteSessionState>>,
16 message_tx: Option<mpsc::Sender<RemoteMessage>>,
18 message_rx: Option<mpsc::Receiver<RemoteMessage>>,
20}
21
22impl RemoteSession {
23 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 pub async fn connect(&mut self) -> anyhow::Result<()> {
42 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 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 self.set_connection_state(ConnectionState::Connecting);
76
77 let (tx, rx) = mpsc::channel(100);
79 self.message_tx = Some(tx);
80 self.message_rx = Some(rx);
81
82 self.set_connection_state(ConnectionState::Connected);
86 Ok(())
87 }
88
89 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 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 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 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 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 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 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
165pub fn create_remote_session(config: TeleportConfig) -> RemoteSession {
167 RemoteSession::new(config)
168}