flare_core/server/connection/
device_handler.rs1use crate::common::MessageParser;
6use crate::common::device::{DeviceInfo, DevicePlatform};
7use crate::common::error::Result;
8use crate::common::protocol::{Reliability, builder::kicked, frame_with_system_command};
9use crate::server::connection::ConnectionManagerTrait;
10use crate::server::device::DeviceManager;
11use std::sync::Arc;
12use tracing::{debug, error, info, warn};
13
14#[derive(Debug)]
16pub struct DeviceConflictResult {
17 pub conflict_connections: Vec<String>,
19}
20
21pub async fn handle_device_conflict(
36 device_manager: Option<Arc<DeviceManager>>,
37 user_id: &str,
38 connection_id: &str,
39 platform: &DevicePlatform,
40 device_info: &DeviceInfo,
41 manager: Arc<dyn ConnectionManagerTrait>,
42) -> Result<DeviceConflictResult> {
43 let mut conflict_connections = Vec::new();
44
45 info!(
46 "[DeviceHandler] 开始处理设备冲突: user_id={}, connection_id={}, platform={:?}",
47 user_id, connection_id, platform
48 );
49
50 let device_manager_clone = device_manager.clone();
51 if let Some(device_mgr) = &device_manager {
52 match device_mgr
54 .add_device(user_id, connection_id.to_string(), device_info.clone())
55 .await
56 {
57 Ok(conflicts) => {
58 conflict_connections = conflicts;
59 if !conflict_connections.is_empty() {
60 info!(
61 "[DeviceHandler] ✅ 设备冲突检测: 用户 {} 的新平台 {:?} 将踢掉 {} 个旧连接: {:?}",
62 user_id,
63 platform,
64 conflict_connections.len(),
65 conflict_connections
66 );
67 } else {
68 debug!(
69 "[DeviceHandler] 无设备冲突: 用户 {} 的新平台 {:?} 可以正常添加",
70 user_id, platform
71 );
72 }
73 }
74 Err(e) => {
75 error!("[DeviceHandler] 设备管理器错误: {}", e);
76 }
77 }
78 } else {
79 debug!("[DeviceHandler] 未配置设备管理器,跳过设备冲突检测");
80 }
81
82 if !conflict_connections.is_empty() {
84 info!(
85 "[DeviceHandler] 准备踢掉 {} 个冲突连接: {:?}",
86 conflict_connections.len(),
87 conflict_connections
88 );
89 }
90
91 if let Some(device_mgr) = device_manager_clone {
92 info!(
93 "[DeviceHandler] 🔍 开始处理 {} 个冲突连接,新连接ID: {}",
94 conflict_connections.len(),
95 connection_id
96 );
97
98 for conflict_conn_id in &conflict_connections {
99 if conflict_conn_id == connection_id {
101 error!(
102 "[DeviceHandler] ❌ 严重错误:冲突连接列表包含新连接ID!跳过处理: connection_id={}",
103 connection_id
104 );
105 continue;
106 }
107
108 info!(
109 "[DeviceHandler] 📤 准备踢掉旧连接: connection_id={} (新连接ID: {})",
110 conflict_conn_id, connection_id
111 );
112
113 if let Some((conn, conn_info)) = manager.get_connection(conflict_conn_id).await {
115 info!(
116 "[DeviceHandler] 找到冲突连接: connection_id={}, user_id={:?}, format={:?}",
117 conflict_conn_id, conn_info.user_id, conn_info.serialization_format
118 );
119 let reason = format!(
121 "设备冲突:同一用户 ({}) 的同一平台 ({:?}) 已有其他设备在线,当前设备将被踢下线",
122 user_id, platform
123 );
124
125 let mut metadata = std::collections::HashMap::new();
126 metadata.insert("reason".to_string(), "device_conflict".as_bytes().to_vec());
127 metadata.insert(
128 "platform".to_string(),
129 format!("{:?}", platform).as_bytes().to_vec(),
130 );
131 metadata.insert(
132 "new_device_id".to_string(),
133 device_info.device_id.as_bytes().to_vec(),
134 );
135
136 let kick_cmd = kicked(reason.clone(), Some(metadata));
137 let kick_frame = frame_with_system_command(kick_cmd, Reliability::AtLeastOnce);
138
139 let parser = MessageParser::new(
141 conn_info.serialization_format,
142 conn_info.compression,
143 crate::common::encryption::EncryptionAlgorithm::None,
144 );
145
146 match parser.serialize(&kick_frame) {
147 Ok(kick_data) => {
148 if conflict_conn_id == connection_id {
150 error!(
151 "[DeviceHandler] ❌ 严重错误:尝试发送KICKED消息给新连接!跳过: connection_id={}",
152 connection_id
153 );
154 continue;
155 }
156
157 let mut c = conn.lock().await;
158 if let Err(e) = c.send(&kick_data).await {
159 error!(
160 "[DeviceHandler] 发送被踢消息失败给旧连接 {}: {}",
161 conflict_conn_id, e
162 );
163 } else {
164 info!(
165 "[DeviceHandler] ✅ 已发送被踢消息给旧连接 {} (新连接: {}): {}",
166 conflict_conn_id, connection_id, reason
167 );
168 info!("[DeviceHandler] 💡 客户端收到 KICKED 消息后将主动断开连接");
169 }
170 }
171 Err(e) => {
172 error!(
173 "[DeviceHandler] 序列化被踢消息失败 (旧连接: {}): {}",
174 conflict_conn_id, e
175 );
176 }
177 }
178
179 if conflict_conn_id == connection_id {
182 error!(
183 "[DeviceHandler] ❌ 严重错误:尝试从设备管理器移除新连接的设备!跳过: connection_id={}",
184 connection_id
185 );
186 continue;
187 }
188
189 match device_mgr.remove_device(user_id, conflict_conn_id).await {
190 Ok(_) => {
191 info!(
192 "[DeviceHandler] ✅ 旧连接的设备已从设备管理器移除: {} (新连接: {})",
193 conflict_conn_id, connection_id
194 );
195 }
196 Err(e) => {
197 debug!(
198 "[DeviceHandler] 旧连接的设备 {} 已不存在于设备管理器: {}",
199 conflict_conn_id, e
200 );
201 }
202 }
203 } else {
204 warn!(
205 "[DeviceHandler] 无法获取旧连接信息: {} (连接可能已断开)",
206 conflict_conn_id
207 );
208 }
209 }
210
211 info!(
212 "[DeviceHandler] ✅ 设备冲突处理完成: 新连接 {} 已保留,已向 {} 个旧连接发送 KICKED 消息",
213 connection_id,
214 conflict_connections.len()
215 );
216 } else {
217 warn!(
219 "[DeviceHandler] ⚠️ 无设备管理器,无法处理设备冲突: {} 个冲突连接",
220 conflict_connections.len()
221 );
222 }
223
224 info!(
225 "[DeviceHandler] 🎯 设备冲突处理完成: 新连接 {} 保留,已通知 {} 个旧连接断开(客户端将主动断开)",
226 connection_id,
227 conflict_connections.len()
228 );
229
230 Ok(DeviceConflictResult {
231 conflict_connections,
232 })
233}