flare_core/server/transports/
hybrid.rs1use super::Server;
7use super::server_core::ServerCore;
8use crate::common::config_types::TransportProtocol;
9use crate::common::error::Result;
10use crate::common::protocol::Frame;
11use crate::server::config::ServerConfig;
12use crate::server::handle::ServerHandle;
13use async_trait::async_trait;
14use std::sync::Arc;
15use std::sync::atomic::{AtomicBool, Ordering};
16use tokio::sync::Mutex;
17use tracing::error;
18
19#[cfg(feature = "quic")]
20use super::quic::QUICServer;
21#[cfg(feature = "tcp")]
22use super::tcp::TCPServer;
23#[cfg(feature = "websocket")]
24use super::websocket::WebSocketServer;
25
26pub struct HybridServer {
31 servers: Vec<Arc<Mutex<Box<dyn Server>>>>,
33 protocols: Vec<TransportProtocol>,
35 is_running: Arc<AtomicBool>,
37 core: Option<Arc<ServerCore>>,
39 config: ServerConfig,
41}
42
43impl HybridServer {
44 pub fn new(config: ServerConfig) -> Result<Self> {
52 Self::with_connection_manager(config, None, None, None, None)
53 }
54
55 pub fn with_connection_manager(
67 config: ServerConfig,
68 connection_manager: Option<Arc<crate::server::connection::ConnectionManager>>,
69 device_manager: Option<Arc<crate::server::device::DeviceManager>>,
70 event_handler: Option<Arc<dyn crate::server::events::handler::ServerEventHandler>>,
71 authenticator: Option<Arc<dyn crate::server::auth::Authenticator>>,
72 ) -> Result<Self> {
73 Self::with_connection_manager_and_pipeline(
74 config,
75 connection_manager,
76 device_manager,
77 event_handler,
78 authenticator,
79 Vec::new(),
80 Vec::new(),
81 )
82 }
83
84 pub fn with_connection_manager_and_pipeline(
98 config: ServerConfig,
99 connection_manager: Option<Arc<crate::server::connection::ConnectionManager>>,
100 device_manager: Option<Arc<crate::server::device::DeviceManager>>,
101 event_handler: Option<Arc<dyn crate::server::events::handler::ServerEventHandler>>,
102 authenticator: Option<Arc<dyn crate::server::auth::Authenticator>>,
103 middlewares: Vec<crate::common::message::pipeline::ArcMessageMiddleware>,
104 processors: Vec<crate::common::message::pipeline::ArcMessageProcessor>,
105 ) -> Result<Self> {
106 let mut core = ServerCore::new(&config, connection_manager.clone());
108
109 let final_device_manager = if let Some(dm) = device_manager {
111 Some(dm)
112 } else if config.device_conflict_strategy
113 != crate::common::device::DeviceConflictStrategy::AllowAll
114 {
115 Some(Arc::new(crate::server::device::DeviceManager::new(
116 config.device_conflict_strategy.clone(),
117 )))
118 } else {
119 None
120 };
121
122 core = core
123 .with_device_manager(final_device_manager)
124 .with_event_handler(event_handler)
125 .with_authenticator(authenticator);
126
127 if !middlewares.is_empty() || !processors.is_empty() {
131 tokio::task::block_in_place(|| {
132 let handle = tokio::runtime::Handle::try_current().map_err(|_| {
133 crate::common::error::FlareError::general_error(
134 "Tokio runtime not available".to_string(),
135 )
136 })?;
137
138 handle.block_on(async {
139 for middleware in middlewares {
140 core.add_middleware(middleware).await;
141 }
142 for processor in processors {
143 core.add_processor(processor).await;
144 }
145 });
146 Ok::<(), crate::common::error::FlareError>(())
147 })
148 .map_err(|e| {
149 crate::common::error::FlareError::general_error(format!(
150 "Failed to add middlewares/processors: {}",
151 e
152 ))
153 })?;
154 }
155
156 let shared_core = Arc::new(core);
158
159 let protocols = config.get_protocols();
160 let mut servers = Vec::new();
161 let mut effective_protocols = Vec::new();
162 let has_websocket = protocols.contains(&TransportProtocol::WebSocket);
163
164 for protocol in &protocols {
165 let mut server_config = config.clone();
166 server_config.transport = *protocol;
167 server_config.transports = None;
168
169 let bind_address = config.get_protocol_address(protocol);
171 server_config.bind_address = bind_address;
172
173 let server_result: Result<Box<dyn Server>> = match protocol {
174 TransportProtocol::WebSocket => {
175 #[cfg(feature = "websocket")]
176 {
177 Ok(Box::new(WebSocketServer::with_shared_core(
178 server_config,
179 shared_core.clone(),
180 )))
181 }
182 #[cfg(not(feature = "websocket"))]
183 {
184 let _ = (server_config, &shared_core);
185 Err(crate::common::error::FlareError::operation_not_supported(
186 "WebSocket server feature is disabled",
187 ))
188 }
189 }
190 TransportProtocol::QUIC => {
191 #[cfg(feature = "quic")]
192 {
193 QUICServer::with_shared_core(server_config, shared_core.clone())
194 .map(|s| Box::new(s) as Box<dyn Server>)
195 }
196 #[cfg(not(feature = "quic"))]
197 {
198 let _ = (server_config, &shared_core);
199 Err(crate::common::error::FlareError::operation_not_supported(
200 "QUIC server feature is disabled",
201 ))
202 }
203 }
204 TransportProtocol::TCP => {
205 #[cfg(feature = "tcp")]
206 {
207 Ok(Box::new(TCPServer::with_shared_core(
208 server_config,
209 shared_core.clone(),
210 )))
211 }
212 #[cfg(not(feature = "tcp"))]
213 {
214 let _ = (server_config, &shared_core);
215 Err(crate::common::error::FlareError::operation_not_supported(
216 "TCP server feature is disabled",
217 ))
218 }
219 }
220 };
221
222 match server_result {
223 Ok(server) => {
224 servers.push(Arc::new(Mutex::new(server)));
225 effective_protocols.push(*protocol);
226 }
227 Err(e) if *protocol == TransportProtocol::QUIC && has_websocket => {
228 tracing::warn!(
229 "QUIC server unavailable ({e}), continuing with WebSocket only (set FLARE_WS_ONLY=1 to skip QUIC bind attempts)"
230 );
231 }
232 Err(e) => return Err(e),
233 }
234 }
235
236 if effective_protocols.is_empty() {
237 return Err(crate::common::error::FlareError::connection_failed(
238 "No transport servers could be started".to_string(),
239 ));
240 }
241
242 Ok(Self {
243 servers,
244 protocols: effective_protocols,
245 is_running: Arc::new(AtomicBool::new(false)),
246 core: Some(shared_core),
247 config,
248 })
249 }
250
251 pub fn protocols(&self) -> &[TransportProtocol] {
253 &self.protocols
254 }
255
256 pub fn core(&self) -> Option<&Arc<ServerCore>> {
258 self.core.as_ref()
259 }
260
261 pub fn core_mut(&mut self) -> Option<&mut Arc<ServerCore>> {
263 self.core.as_mut()
264 }
265}
266
267#[async_trait::async_trait]
268impl Server for HybridServer {
269 async fn start(&mut self) -> Result<()> {
270 if let Some(ref mut core) = self.core {
272 core.start_heartbeat(&self.config);
273 }
274
275 let mut started_count = 0;
276 let mut errors = Vec::new();
277
278 for server in &self.servers {
280 let mut s = server.lock().await;
281 match s.start().await {
282 Ok(_) => {
283 started_count += 1;
284 }
285 Err(e) => {
286 error!("Failed to start server: {:?}", e);
287 errors.push(e);
288 }
289 }
290 }
291
292 if started_count == 0 && !errors.is_empty() {
294 self.is_running.store(false, Ordering::SeqCst);
295 return Err(errors.remove(0));
296 }
297
298 if started_count > 0 {
300 self.is_running.store(true, Ordering::SeqCst);
301 }
302
303 Ok(())
304 }
305
306 async fn stop(&mut self) -> Result<()> {
307 self.is_running.store(false, Ordering::SeqCst);
308
309 if let Some(ref mut core) = self.core {
311 core.stop_heartbeat();
312 }
313
314 for server in &self.servers {
316 let mut s = server.lock().await;
317 if let Err(e) = s.stop().await {
318 error!("Failed to stop server: {:?}", e);
319 }
320 }
321
322 Ok(())
323 }
324
325 fn is_running(&self) -> bool {
326 self.is_running.load(Ordering::SeqCst)
327 }
328}
329
330#[async_trait]
333impl ServerHandle for HybridServer {
334 async fn send_to(&self, connection_id: &str, frame: &Frame) -> Result<()> {
335 if let Some(ref core) = self.core {
337 return ServerHandle::send_to(&**core, connection_id, frame).await;
338 }
339 Err(crate::common::error::FlareError::protocol_error(
340 "ServerCore not initialized".to_string(),
341 ))
342 }
343
344 async fn send_to_user(&self, user_id: &str, frame: &Frame) -> Result<()> {
345 if let Some(ref core) = self.core {
347 return ServerHandle::send_to_user(&**core, user_id, frame).await;
348 }
349 Err(crate::common::error::FlareError::protocol_error(
350 "ServerCore not initialized".to_string(),
351 ))
352 }
353
354 async fn broadcast(&self, frame: &Frame) -> Result<()> {
355 if let Some(ref core) = self.core {
357 return ServerHandle::broadcast(&**core, frame).await;
358 }
359 Err(crate::common::error::FlareError::protocol_error(
360 "ServerCore not initialized".to_string(),
361 ))
362 }
363
364 async fn broadcast_except(&self, frame: &Frame, exclude_connection_id: &str) -> Result<()> {
365 if let Some(ref core) = self.core {
367 return ServerHandle::broadcast_except(&**core, frame, exclude_connection_id).await;
368 }
369 Err(crate::common::error::FlareError::protocol_error(
370 "ServerCore not initialized".to_string(),
371 ))
372 }
373
374 async fn disconnect(&self, connection_id: &str) -> Result<()> {
375 if let Some(ref core) = self.core {
377 return ServerHandle::disconnect(&**core, connection_id).await;
378 }
379 Err(crate::common::error::FlareError::protocol_error(
380 "ServerCore not initialized".to_string(),
381 ))
382 }
383
384 fn connection_count(&self) -> usize {
385 if let Some(ref core) = self.core {
387 return ServerHandle::connection_count(&**core);
388 }
389 0
390 }
391
392 fn user_count(&self) -> usize {
393 if let Some(ref core) = self.core {
395 return ServerHandle::user_count(&**core);
396 }
397 0
398 }
399}