Skip to main content

flare_core/server/connection/manager/
ops.rs

1use super::*;
2
3impl ConnectionManager {
4    /// 获取用户的所有连接
5    ///
6    /// # 参数
7    /// - `user_id`: 用户 ID
8    ///
9    /// # 返回
10    /// 该用户的所有连接 ID 列表
11    pub fn get_user_connections(&self, user_id: &str) -> Vec<String> {
12        self.user_connection_shard(user_id)
13            .read()
14            .ok()
15            .and_then(|user_connections| user_connections.get(user_id).cloned())
16            .unwrap_or_default()
17    }
18
19    /// 更新连接的用户 ID(用于认证后绑定用户)
20    ///
21    /// # 参数
22    /// - `connection_id`: 连接 ID
23    /// - `user_id`: 新的用户 ID
24    pub fn bind_user(&self, connection_id: &str, user_id: String) -> Result<()> {
25        let mut shard = self
26            .connection_shard(connection_id)
27            .write()
28            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
29
30        let (_, _, info) = shard.get_mut(connection_id).ok_or_else(|| {
31            FlareError::protocol_error(format!("Connection {} not found", connection_id))
32        })?;
33
34        // 如果之前有用户 ID,先移除旧映射
35        if let Some(old_user_id) = &info.user_id {
36            self.remove_user_connection(old_user_id, connection_id)?;
37        }
38
39        // 更新用户 ID
40        info.user_id = Some(user_id.clone());
41
42        // 添加到新用户映射
43        self.insert_user_connection(user_id, connection_id)?;
44
45        Ok(())
46    }
47
48    /// 更新连接的最后活跃时间
49    pub fn update_connection_active(&self, connection_id: &str) -> Result<()> {
50        let mut shard = self
51            .connection_shard(connection_id)
52            .write()
53            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
54
55        if let Some((_, _, info)) = shard.get_mut(connection_id) {
56            info.update_active();
57            drop(shard);
58            Ok(())
59        } else {
60            drop(shard);
61            Err(FlareError::protocol_error(format!(
62                "Connection {} not found",
63                connection_id
64            )))
65        }
66    }
67
68    pub(super) fn update_connections_active<I>(&self, connection_ids: I) -> usize
69    where
70        I: IntoIterator<Item = String>,
71    {
72        let now = Instant::now();
73        let mut ids_by_shard = vec![Vec::new(); self.connection_shards.len()];
74        for connection_id in connection_ids {
75            let shard_index = self.connection_shard_index(&connection_id);
76            ids_by_shard[shard_index].push(connection_id);
77        }
78
79        ids_by_shard
80            .into_iter()
81            .enumerate()
82            .map(|(shard_index, ids)| {
83                if ids.is_empty() {
84                    return 0;
85                }
86
87                let Ok(mut shard) = self.connection_shards[shard_index].write() else {
88                    return 0;
89                };
90
91                let mut updated = 0;
92                for connection_id in ids {
93                    if let Some((_, _, info)) = shard.get_mut(&connection_id) {
94                        info.last_active = now;
95                        updated += 1;
96                    }
97                }
98                updated
99            })
100            .sum()
101    }
102
103    pub(super) fn record_successful_connection_id(
104        successful_ids: &Arc<std::sync::Mutex<Vec<String>>>,
105        connection_id: String,
106    ) {
107        if let Ok(mut ids) = successful_ids.lock() {
108            ids.push(connection_id);
109        }
110    }
111
112    pub(super) fn take_successful_connection_ids(
113        successful_ids: Arc<std::sync::Mutex<Vec<String>>>,
114    ) -> Vec<String> {
115        Arc::try_unwrap(successful_ids)
116            .ok()
117            .and_then(|ids| ids.into_inner().ok())
118            .unwrap_or_default()
119    }
120
121    /// 设置连接为已验证状态
122    pub fn set_connection_authenticated(
123        &self,
124        connection_id: &str,
125        user_id: Option<String>,
126    ) -> Result<()> {
127        let mut shard = self
128            .connection_shard(connection_id)
129            .write()
130            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
131
132        let (_, _, info) = shard.get_mut(connection_id).ok_or_else(|| {
133            FlareError::protocol_error(format!("Connection {} not found", connection_id))
134        })?;
135
136        // 保存旧的 user_id(在调用 set_authenticated 之前)
137        let old_user_id = info.user_id.clone();
138
139        let final_user_id = user_id.or(old_user_id.clone());
140
141        // 设置认证状态(如果 final_user_id 是 Some,会设置 user_id)
142        info.set_authenticated(final_user_id.clone());
143
144        // 如果有 user_id(传入的或已存在的),确保用户连接映射正确
145        if let Some(user_id) = final_user_id {
146            // 如果 user_id 发生变化,需要更新映射
147            let user_id_changed = old_user_id
148                .as_ref()
149                .map(|old| old != &user_id)
150                .unwrap_or(true);
151
152            if user_id_changed {
153                // 如果之前有旧用户 ID,先移除旧映射
154                if let Some(old_user_id) = old_user_id {
155                    self.remove_user_connection(&old_user_id, connection_id)?;
156                }
157
158                // 添加新映射(检查是否已存在,避免重复)
159                self.insert_user_connection(user_id, connection_id)?;
160            } else {
161                // user_id 没有变化,只需确保映射存在
162                self.insert_user_connection(user_id, connection_id)?;
163            }
164        }
165
166        Ok(())
167    }
168
169    /// 更新连接的协商信息(设备信息、序列化格式、压缩算法)
170    #[allow(clippy::too_many_arguments)]
171    pub fn update_connection_negotiation(
172        &self,
173        connection_id: &str,
174        device_info: Option<crate::common::device::DeviceInfo>,
175        serialization_format: crate::common::protocol::SerializationFormat,
176        compression: crate::common::compression::CompressionAlgorithm,
177        encryption: crate::common::encryption::EncryptionAlgorithm,
178        user_id: Option<String>,
179        metadata: Option<HashMap<String, String>>,
180    ) -> Result<()> {
181        let mut shard = self
182            .connection_shard(connection_id)
183            .write()
184            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
185
186        let (_, _, info) = shard.get_mut(connection_id).ok_or_else(|| {
187            FlareError::protocol_error(format!("Connection {} not found", connection_id))
188        })?;
189
190        // 更新协商信息(但不标记协商完成)
191        // 协商完成将在 CONNECT_ACK 发送完成后由 update_connection_negotiation_with_pipeline 标记
192        info.device_info = device_info;
193        info.serialization_format = serialization_format;
194        info.compression = compression;
195        info.encryption = encryption;
196        // 若有传入 metadata,将其所有键值合并到 ConnectionInfo.metadata(同 key 覆盖)
197        if let Some(meta) = metadata {
198            for (k, v) in meta {
199                info.metadata.insert(k, v);
200            }
201        }
202        // 注意:这里不设置 negotiation_completed = true
203        // 也不创建 cached_parser,这些将在 CONNECT_ACK 发送完成后设置
204
205        // 保存旧的 user_id(在修改之前)
206        let old_user_id = info.user_id.clone();
207
208        let user_id_to_set = user_id.clone().or(old_user_id.clone());
209
210        // 添加调试日志
211        if user_id_to_set.is_none() {
212            tracing::trace!(connection_id = %connection_id,incoming_user_id = ?user_id,old_user_id = ?old_user_id,"update_connection_negotiation: user_id_to_set is None, user_id will not be set");
213        }
214
215        if let Some(user_id_val) = user_id_to_set {
216            // 如果之前有用户 ID 且与新 user_id 不同,先移除旧映射
217            if let Some(old_user_id) = old_user_id
218                && old_user_id != user_id_val
219            {
220                self.remove_user_connection(&old_user_id, connection_id)?;
221            }
222
223            // 更新用户 ID
224            info.user_id = Some(user_id_val.clone());
225
226            // 添加到新用户映射
227            self.insert_user_connection(user_id_val, connection_id)?;
228        }
229
230        Ok(())
231    }
232
233    /// 更新连接的协商信息(设备信息、序列化格式、压缩算法、加密方式)并设置 pipeline
234    #[allow(clippy::too_many_arguments)]
235    pub fn update_connection_negotiation_with_pipeline(
236        &self,
237        connection_id: &str,
238        device_info: Option<crate::common::device::DeviceInfo>,
239        serialization_format: crate::common::protocol::SerializationFormat,
240        compression: crate::common::compression::CompressionAlgorithm,
241        encryption: crate::common::encryption::EncryptionAlgorithm,
242        user_id: Option<String>,
243        parser: crate::common::MessageParser,
244        pipeline: Option<std::sync::Arc<crate::common::message::pipeline::MessagePipeline>>,
245    ) -> Result<()> {
246        let mut shard = self
247            .connection_shard(connection_id)
248            .write()
249            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
250
251        let (_, _, info) = shard.get_mut(connection_id).ok_or_else(|| {
252            FlareError::protocol_error(format!("Connection {} not found", connection_id))
253        })?;
254
255        // 更新协商信息
256        info.device_info = device_info;
257        info.serialization_format = serialization_format;
258        info.compression = compression;
259        info.encryption = encryption;
260        // 标记协商已完成
261        info.negotiation_completed = true;
262        // 缓存 parser 和 pipeline
263        info.cached_parser = Some(std::sync::Arc::new(parser));
264        info.cached_pipeline = pipeline;
265
266        // 保存旧的 user_id(在修改之前)
267        let old_user_id = info.user_id.clone();
268
269        let user_id_to_set = user_id.clone().or(old_user_id.clone());
270
271        // 添加调试日志
272        if user_id_to_set.is_none() {
273            tracing::trace!(
274                connection_id = %connection_id,
275                incoming_user_id = ?user_id,
276                old_user_id = ?old_user_id,
277                "update_connection_negotiation_with_pipeline: user_id_to_set is None, user_id will not be set"
278            );
279        }
280
281        if let Some(user_id_val) = user_id_to_set {
282            // 如果之前有用户 ID 且与新 user_id 不同,先移除旧映射
283            if let Some(old_user_id) = old_user_id
284                && old_user_id != user_id_val
285            {
286                self.remove_user_connection(&old_user_id, connection_id)?;
287            }
288
289            // 更新用户 ID
290            info.user_id = Some(user_id_val.clone());
291
292            // 添加到新用户映射
293            self.insert_user_connection(user_id_val, connection_id)?;
294        }
295
296        Ok(())
297    }
298
299    /// 标记协商已确认(客户端收到 CONNECT_ACK 后发送确认)
300    pub fn mark_negotiation_confirmed(&self, connection_id: &str) -> Result<()> {
301        let mut shard = self
302            .connection_shard(connection_id)
303            .write()
304            .map_err(|_| FlareError::general_error("Failed to lock connection shard"))?;
305
306        let (_, _, info) = shard.get_mut(connection_id).ok_or_else(|| {
307            FlareError::protocol_error(format!("Connection {} not found", connection_id))
308        })?;
309
310        if !info.negotiation_completed {
311            return Err(FlareError::protocol_error(format!(
312                "Cannot confirm negotiation for connection {}: negotiation not completed",
313                connection_id
314            )));
315        }
316
317        info.negotiation_confirmed = true;
318        tracing::trace!(
319            "[ConnectionManager] 协商已确认: connection_id={}",
320            connection_id
321        );
322
323        Ok(())
324    }
325
326    /// 获取所有连接 ID
327    pub fn list_connections(&self) -> Vec<String> {
328        self.connection_shards
329            .iter()
330            .flat_map(|shard| {
331                shard
332                    .read()
333                    .ok()
334                    .map(|connections| connections.keys().cloned().collect::<Vec<_>>())
335                    .unwrap_or_default()
336            })
337            .collect()
338    }
339
340    /// 获取连接总数
341    pub fn connection_count(&self) -> usize {
342        self.connection_count.load(Ordering::Relaxed)
343    }
344
345    /// 获取当前绑定了连接的用户数
346    pub fn user_count(&self) -> usize {
347        self.user_count.load(Ordering::Relaxed)
348    }
349
350    /// 清理超时连接
351    ///
352    /// # 参数
353    /// - `timeout`: 超时时间
354    ///
355    /// # 返回
356    /// 被清理的连接 ID 列表
357    pub fn cleanup_timeout_connections(&self, timeout: Duration) -> Vec<String> {
358        let timeout_connections = self.timeout_connection_snapshots(timeout);
359        self.remove_connection_snapshots(
360            timeout_connections
361                .iter()
362                .map(|(connection_id, _, _)| connection_id.clone()),
363        )
364    }
365
366    /// 获取连接统计信息
367    pub fn stats(&self) -> TraitConnectionStats {
368        let total_connections = self.connection_count();
369        let total_users = self.user_count();
370
371        TraitConnectionStats {
372            total_connections,
373            total_users,
374        }
375    }
376
377    pub(super) fn frame_allowed_before_auth(frame: &crate::common::protocol::Frame) -> bool {
378        frame
379            .command
380            .as_ref()
381            .and_then(|cmd| {
382                if let Some(crate::common::protocol::flare::core::commands::command::Type::System(
383                    sys_cmd,
384                )) = &cmd.r#type
385                {
386                    Some(
387                        sys_cmd.r#type
388                            == crate::common::protocol::flare::core::commands::system_command::Type::ConnectAck
389                                as i32
390                            || sys_cmd.r#type
391                                == crate::common::protocol::flare::core::commands::system_command::Type::Ping
392                                    as i32
393                            || sys_cmd.r#type
394                                == crate::common::protocol::flare::core::commands::system_command::Type::Pong
395                                    as i32
396                            || sys_cmd.r#type
397                                == crate::common::protocol::flare::core::commands::system_command::Type::Error
398                                    as i32
399                            || sys_cmd.r#type
400                                == crate::common::protocol::flare::core::commands::system_command::Type::Close
401                                    as i32,
402                    )
403                } else {
404                    None
405                }
406            })
407            .unwrap_or(false)
408    }
409
410    pub(super) fn serialize_frame_for_connection(
411        connection_id: &str,
412        info: &ConnectionInfo,
413        frame: &crate::common::protocol::Frame,
414        parser: Option<&crate::common::MessageParser>,
415    ) -> Result<Vec<u8>> {
416        Self::ensure_frame_allowed_for_connection(connection_id, info, frame)?;
417
418        if let Some(parser) = parser {
419            return parser.serialize(frame);
420        }
421
422        if let Some(parser) = &info.cached_parser {
423            return parser.serialize(frame);
424        }
425
426        crate::common::MessageParser::new(
427            info.serialization_format,
428            info.compression.clone(),
429            info.encryption.clone(),
430        )
431        .serialize(frame)
432    }
433
434    pub(super) fn ensure_frame_allowed_for_connection(
435        connection_id: &str,
436        info: &ConnectionInfo,
437        frame: &crate::common::protocol::Frame,
438    ) -> Result<()> {
439        if info.authenticated || Self::frame_allowed_before_auth(frame) {
440            return Ok(());
441        }
442
443        Err(FlareError::authentication_failed(format!(
444            "连接 {} 未验证,无法发送消息",
445            connection_id
446        )))
447    }
448
449    pub(super) async fn send_to_connection_handle(
450        &self,
451        connection_id: &str,
452        connection: ConnectionWriteHandle,
453        data: &[u8],
454    ) -> Result<()> {
455        match connection.try_enqueue(data) {
456            Ok(()) => Ok(()),
457            Err(err) => {
458                connection.close_underlying_in_background();
459                let _ = ConnectionManager::remove_connection(self, connection_id);
460                Err(err)
461            }
462        }
463    }
464
465    pub(super) async fn send_frame_to_snapshot(
466        &self,
467        snapshot: ConnectionSnapshot,
468        frame: &crate::common::protocol::Frame,
469        parser: Option<&crate::common::MessageParser>,
470    ) -> Result<()> {
471        let connection_id = self
472            .send_frame_to_snapshot_without_active(snapshot, frame, parser)
473            .await?;
474        ConnectionManager::update_connection_active(self, &connection_id)?;
475        Ok(())
476    }
477
478    pub(super) async fn send_frame_to_snapshot_without_active(
479        &self,
480        snapshot: ConnectionSnapshot,
481        frame: &crate::common::protocol::Frame,
482        parser: Option<&crate::common::MessageParser>,
483    ) -> Result<String> {
484        let (connection_id, connection, info) = snapshot;
485        let data = Self::serialize_frame_for_connection(&connection_id, &info, frame, parser)?;
486
487        self.send_to_connection_handle(&connection_id, connection, &data)
488            .await?;
489        Ok(connection_id)
490    }
491
492    pub(super) async fn send_serialized_frame_to_auth_snapshot_without_active(
493        &self,
494        snapshot: ConnectionAuthSnapshot,
495        frame: &crate::common::protocol::Frame,
496        data: &[u8],
497    ) -> Result<String> {
498        let (connection_id, connection, authenticated) = snapshot;
499        if !authenticated && !Self::frame_allowed_before_auth(frame) {
500            return Err(FlareError::authentication_failed(format!(
501                "连接 {} 未验证,无法发送消息",
502                connection_id
503            )));
504        }
505
506        self.send_to_connection_handle(&connection_id, connection, data)
507            .await?;
508        Ok(connection_id)
509    }
510}