flare_core/server/device/
manager.rs1use crate::common::device::{DeviceConflictStrategy, DeviceInfo, DevicePlatform};
6use crate::common::error::Result;
7use std::collections::{HashMap, HashSet};
8use std::sync::Arc;
9use tokio::sync::RwLock;
10use tracing::{debug, info, warn};
11
12#[derive(Debug, Clone)]
14struct UserDevice {
15 connection_id: String,
17 device_info: DeviceInfo,
19}
20
21pub struct DeviceManager {
25 user_devices: Arc<RwLock<HashMap<String, HashMap<String, UserDevice>>>>,
27 conflict_strategy: DeviceConflictStrategy,
29}
30
31impl DeviceManager {
32 pub fn new(conflict_strategy: DeviceConflictStrategy) -> Self {
34 Self {
35 user_devices: Arc::new(RwLock::new(HashMap::new())),
36 conflict_strategy,
37 }
38 }
39
40 pub async fn add_device(
51 &self,
52 user_id: &str,
53 connection_id: String,
54 device_info: DeviceInfo,
55 ) -> Result<Vec<String>> {
56 let mut user_devices = self.user_devices.write().await;
57
58 let user_device_map = user_devices
60 .entry(user_id.to_string())
61 .or_insert_with(HashMap::new);
62
63 let existing_platforms: HashSet<DevicePlatform> = user_device_map
65 .values()
66 .map(|d| d.device_info.platform.clone())
67 .collect();
68
69 info!(
70 "[DeviceManager] 添加设备: user_id={}, connection_id={}, platform={:?}, 现有设备数={}, 现有平台={:?}",
71 user_id,
72 connection_id,
73 device_info.platform,
74 user_device_map.len(),
75 existing_platforms
76 );
77
78 let platform = device_info.platform.clone();
80 let conflicts = match self
81 .conflict_strategy
82 .check_conflict(platform.clone(), &existing_platforms)
83 {
84 Ok(_) => {
85 debug!("[DeviceManager] 无冲突,允许添加设备");
86 Vec::new()
87 }
88 Err(conflict_platforms) => {
89 info!(
90 "[DeviceManager] 检测到冲突: 新平台={:?}, 冲突平台={:?}",
91 platform, conflict_platforms
92 );
93 let mut conflict_connections = Vec::new();
95 for (conn_id, device) in user_device_map.iter() {
96 if conn_id == &connection_id {
98 continue;
99 }
100 if conflict_platforms.contains(&device.device_info.platform) {
101 info!(
102 "[DeviceManager] 发现冲突连接: connection_id={}, platform={:?} (新连接ID: {})",
103 conn_id, device.device_info.platform, connection_id
104 );
105 conflict_connections.push(conn_id.clone());
106 }
107 }
108 if conflict_connections.is_empty() {
109 warn!(
110 "[DeviceManager] 警告:检测到冲突但未找到冲突连接,现有设备: {:?}",
111 user_device_map.keys().collect::<Vec<_>>()
112 );
113 }
114 conflict_connections
115 }
116 };
117
118 for conn_id in &conflicts {
120 user_device_map.remove(conn_id);
121 info!("[DeviceManager] 已移除冲突设备: connection_id={}", conn_id);
122 }
123
124 user_device_map.insert(
126 connection_id.clone(),
127 UserDevice {
128 connection_id: connection_id.clone(),
129 device_info,
130 },
131 );
132 info!(
133 "[DeviceManager] 新设备已添加: user_id={}, connection_id={}, 当前设备数={}",
134 user_id,
135 connection_id,
136 user_device_map.len()
137 );
138
139 Ok(conflicts)
140 }
141
142 pub async fn remove_device(&self, user_id: &str, connection_id: &str) -> Result<()> {
144 let mut user_devices = self.user_devices.write().await;
145
146 if let Some(devices) = user_devices.get_mut(user_id) {
147 devices.remove(connection_id);
148
149 if devices.is_empty() {
151 user_devices.remove(user_id);
152 }
153 }
154
155 Ok(())
156 }
157
158 pub async fn get_user_devices(&self, user_id: &str) -> Vec<DeviceInfo> {
160 let user_devices = self.user_devices.read().await;
161
162 user_devices
163 .get(user_id)
164 .map(|devices| devices.values().map(|d| d.device_info.clone()).collect())
165 .unwrap_or_default()
166 }
167
168 pub async fn get_user_connections(&self, user_id: &str) -> Vec<String> {
170 let user_devices = self.user_devices.read().await;
171
172 user_devices
173 .get(user_id)
174 .map(|devices| devices.keys().cloned().collect())
175 .unwrap_or_default()
176 }
177
178 pub async fn get_device_connection(&self, user_id: &str, device_id: &str) -> Option<String> {
180 let user_devices = self.user_devices.read().await;
181
182 user_devices.get(user_id).and_then(|devices| {
183 devices
184 .values()
185 .find(|d| d.device_info.device_id == device_id)
186 .map(|d| d.connection_id.clone())
187 })
188 }
189
190 pub fn update_strategy(&mut self, strategy: DeviceConflictStrategy) {
192 self.conflict_strategy = strategy;
193 }
194}