flare_core/server/connection/manager/
ops.rs1use super::*;
2
3impl ConnectionManager {
4 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 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 if let Some(old_user_id) = &info.user_id {
36 self.remove_user_connection(old_user_id, connection_id)?;
37 }
38
39 info.user_id = Some(user_id.clone());
41
42 self.insert_user_connection(user_id, connection_id)?;
44
45 Ok(())
46 }
47
48 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 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 let old_user_id = info.user_id.clone();
138
139 let final_user_id = user_id.or(old_user_id.clone());
140
141 info.set_authenticated(final_user_id.clone());
143
144 if let Some(user_id) = final_user_id {
146 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 if let Some(old_user_id) = old_user_id {
155 self.remove_user_connection(&old_user_id, connection_id)?;
156 }
157
158 self.insert_user_connection(user_id, connection_id)?;
160 } else {
161 self.insert_user_connection(user_id, connection_id)?;
163 }
164 }
165
166 Ok(())
167 }
168
169 #[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 info.device_info = device_info;
193 info.serialization_format = serialization_format;
194 info.compression = compression;
195 info.encryption = encryption;
196 if let Some(meta) = metadata {
198 for (k, v) in meta {
199 info.metadata.insert(k, v);
200 }
201 }
202 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 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 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 info.user_id = Some(user_id_val.clone());
225
226 self.insert_user_connection(user_id_val, connection_id)?;
228 }
229
230 Ok(())
231 }
232
233 #[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 info.device_info = device_info;
257 info.serialization_format = serialization_format;
258 info.compression = compression;
259 info.encryption = encryption;
260 info.negotiation_completed = true;
262 info.cached_parser = Some(std::sync::Arc::new(parser));
264 info.cached_pipeline = pipeline;
265
266 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 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 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 info.user_id = Some(user_id_val.clone());
291
292 self.insert_user_connection(user_id_val, connection_id)?;
294 }
295
296 Ok(())
297 }
298
299 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 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 pub fn connection_count(&self) -> usize {
342 self.connection_count.load(Ordering::Relaxed)
343 }
344
345 pub fn user_count(&self) -> usize {
347 self.user_count.load(Ordering::Relaxed)
348 }
349
350 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 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}