flare_core/client/builder/
flare.rs1#[cfg(not(target_arch = "wasm32"))]
28use crate::client::HybridClient;
29#[cfg(target_arch = "wasm32")]
30use crate::client::WebSocketClient;
31use crate::client::builder::{BaseClientBuilderConfig, ClientWrapper};
32use crate::common::MessageParser;
33use crate::common::config_types::{HeartbeatAppState, HeartbeatConfig};
34use crate::common::error::Result;
35use crate::common::message::{
36 ArcMessageMiddleware, ArcMessageProcessor, MessageContext, MessagePipeline, MessageProcessor,
37};
38use crate::common::protocol::Frame;
39use crate::common::protocol::flare::core::commands::command::Type as CommandType;
40use crate::transport::events::{ConnectionEvent, ConnectionObserver};
41use async_trait::async_trait;
42use std::sync::Arc;
43use tokio::sync::Mutex;
44use tracing::{debug, error, info, warn};
45
46#[async_trait]
50pub trait MessageListener: Send + Sync {
51 async fn on_message(&self, frame: &Frame) -> Result<Option<Frame>> {
61 let _ = frame;
62 Ok(None)
63 }
64
65 async fn on_connect(&self) -> Result<()> {
67 Ok(())
68 }
69
70 async fn on_disconnect(&self, reason: Option<&str>) -> Result<()> {
72 let _ = reason;
73 Ok(())
74 }
75
76 async fn on_error(&self, error: &str) -> Result<()> {
78 let _ = error;
79 Ok(())
80 }
81}
82
83pub struct FlareClientBuilder {
93 base: BaseClientBuilderConfig,
94 listener: Option<Arc<dyn MessageListener>>,
95 middlewares: Vec<ArcMessageMiddleware>,
96 processors: Vec<ArcMessageProcessor>,
97 observers: Vec<Arc<dyn ConnectionObserver>>,
98}
99
100impl FlareClientBuilder {
101 pub fn new(server_url: impl Into<String>) -> Self {
103 Self {
104 base: BaseClientBuilderConfig::new(server_url),
105 listener: None,
106 middlewares: Vec::new(),
107 processors: Vec::new(),
108 observers: Vec::new(),
109 }
110 }
111
112 pub fn with_listener(mut self, listener: Arc<dyn MessageListener>) -> Self {
114 self.listener = Some(listener);
115 self
116 }
117
118 pub fn with_middleware(mut self, middleware: ArcMessageMiddleware) -> Self {
120 self.middlewares.push(middleware);
121 self
122 }
123
124 pub fn with_processor(mut self, processor: ArcMessageProcessor) -> Self {
126 self.processors.push(processor);
127 self
128 }
129
130 pub fn with_observer(mut self, observer: Arc<dyn ConnectionObserver>) -> Self {
171 self.observers.push(observer);
172 self
173 }
174
175 pub fn with_protocol(
181 mut self,
182 protocol: crate::common::config_types::TransportProtocol,
183 ) -> Self {
184 self.base = self.base.with_protocol(protocol);
185 self
186 }
187
188 pub fn with_protocol_race(
190 mut self,
191 protocols: Vec<crate::common::config_types::TransportProtocol>,
192 ) -> Self {
193 self.base = self.base.with_protocol_race(protocols);
194 self
195 }
196
197 pub fn with_protocol_url(
199 mut self,
200 protocol: crate::common::config_types::TransportProtocol,
201 url: String,
202 ) -> Self {
203 self.base = self.base.with_protocol_url(protocol, url);
204 self
205 }
206
207 pub fn with_user_id(mut self, user_id: String) -> Self {
209 self.base = self.base.with_user_id(user_id);
210 self
211 }
212
213 pub fn with_format(mut self, format: crate::common::protocol::SerializationFormat) -> Self {
215 self.base = self.base.with_format(format);
216 self
217 }
218
219 pub fn with_compression(
221 mut self,
222 compression: crate::common::compression::CompressionAlgorithm,
223 ) -> Self {
224 self.base = self.base.with_compression(compression);
225 self
226 }
227
228 pub fn force_format(mut self, format: crate::common::protocol::SerializationFormat) -> Self {
230 self.base = self.base.force_format(format);
231 self
232 }
233
234 pub fn force_compression(
236 mut self,
237 compression: crate::common::compression::CompressionAlgorithm,
238 ) -> Self {
239 self.base = self.base.force_compression(compression);
240 self
241 }
242
243 pub fn with_device_info(mut self, device_info: crate::common::device::DeviceInfo) -> Self {
245 self.base = self.base.with_device_info(device_info);
246 self
247 }
248
249 pub fn with_heartbeat(
251 mut self,
252 heartbeat: crate::common::config_types::HeartbeatConfig,
253 ) -> Self {
254 self.base = self.base.with_heartbeat(heartbeat);
255 self
256 }
257
258 pub fn with_tls(mut self, tls: crate::common::config_types::TlsConfig) -> Self {
260 self.base = self.base.with_tls(tls);
261 self
262 }
263
264 pub fn with_connect_timeout(mut self, timeout: std::time::Duration) -> Self {
266 self.base = self.base.with_connect_timeout(timeout);
267 self
268 }
269
270 pub fn with_race_timeout(mut self, timeout: std::time::Duration) -> Self {
272 self.base = self.base.with_race_timeout(timeout);
273 self
274 }
275
276 pub fn with_reconnect_interval(mut self, interval: std::time::Duration) -> Self {
278 self.base = self.base.with_reconnect_interval(interval);
279 self
280 }
281
282 pub fn with_max_reconnect_attempts(mut self, attempts: Option<u32>) -> Self {
284 self.base = self.base.with_max_reconnect_attempts(attempts);
285 self
286 }
287
288 pub fn with_token(mut self, token: String) -> Self {
290 self.base = self.base.with_token(token);
291 self
292 }
293
294 pub fn enable_router(mut self) -> Self {
296 self.base = self.base.enable_router();
297 self
298 }
299
300 pub async fn build_with_race(self) -> Result<FlareClient> {
302 let listener = self.listener.ok_or_else(|| {
303 crate::common::error::FlareError::protocol_error(
304 "MessageListener is required".to_string(),
305 )
306 })?;
307
308 use crate::common::message::parser::PRE_NEGOTIATION_PARSER;
309
310 #[cfg(target_arch = "wasm32")]
312 let client = WebSocketClient::connect_with_config(self.base.config.clone()).await?;
313
314 let pipeline = Arc::new(Mutex::new(MessagePipeline::new(
315 PRE_NEGOTIATION_PARSER.clone(),
316 )));
317
318 for middleware in self.middlewares {
319 pipeline.lock().await.add_middleware(middleware).await;
320 }
321
322 let listener_processor = Arc::new(ListenerProcessor {
323 listener: listener.clone(),
324 });
325 pipeline
326 .lock()
327 .await
328 .add_processor(listener_processor)
329 .await;
330
331 for processor in self.processors {
332 pipeline.lock().await.add_processor(processor).await;
333 }
334
335 #[cfg(not(target_arch = "wasm32"))]
336 let client = HybridClient::connect_with_race(self.base.config.clone()).await?;
337
338 let wrapper = ClientWrapper::new(client);
339
340 let observer = Arc::new(FlareObserver {
342 pipeline: pipeline.clone(),
343 listener: listener.clone(),
344 });
345
346 let observer_clone = observer.clone();
347
348 wrapper.add_observer(observer_clone).await;
352 for observer in self.observers {
353 wrapper.add_observer(observer).await;
354 }
355
356 wrapper
357 .wait_for_negotiation(std::time::Duration::from_secs(10))
358 .await?;
359 let parser = wrapper.parser_snapshot().await;
360 pipeline.lock().await.update_parser(parser).await;
361
362 Ok(FlareClient {
363 wrapper,
364 pipeline,
365 listener,
366 })
367 }
368}
369
370#[derive(Clone)]
372pub struct FlareClient {
373 wrapper: ClientWrapper,
374 #[allow(dead_code)] pipeline: Arc<Mutex<MessagePipeline>>,
376 #[allow(dead_code)] listener: Arc<dyn MessageListener>,
378}
379
380impl FlareClient {
381 pub async fn send_frame(&self, frame: &Frame) -> Result<()> {
383 self.wrapper.send_frame(frame).await
384 }
385
386 pub async fn send_frame_and_wait(
388 &self,
389 frame: &Frame,
390 timeout: std::time::Duration,
391 ) -> Result<Frame> {
392 self.wrapper.send_frame_and_wait(frame, timeout).await
393 }
394
395 #[cfg(not(target_arch = "wasm32"))]
397 pub fn is_connected(&self) -> bool {
398 crate::client::runtime::run_client_async(self.is_connected_async())
399 }
400
401 pub async fn is_connected_async(&self) -> bool {
403 self.wrapper.is_connected_async().await
404 }
405
406 pub async fn disconnect(self) -> Result<()> {
408 self.wrapper.disconnect().await
409 }
410
411 #[cfg(not(target_arch = "wasm32"))]
413 pub fn connection_id(&self) -> Option<String> {
414 crate::client::runtime::run_client_async(self.connection_id_async())
415 }
416
417 pub async fn connection_id_async(&self) -> Option<String> {
419 self.wrapper.connection_id_async().await
420 }
421
422 pub async fn parser_snapshot(&self) -> MessageParser {
424 self.wrapper.parser_snapshot().await
425 }
426
427 pub fn active_protocol(&self) -> crate::common::config_types::TransportProtocol {
429 self.wrapper.active_protocol()
430 }
431
432 pub async fn update_heartbeat_config(&self, config: HeartbeatConfig) {
434 self.wrapper.update_heartbeat_config(config).await;
435 }
436
437 pub async fn set_heartbeat_app_state(&self, state: HeartbeatAppState) {
439 self.wrapper.set_heartbeat_app_state(state).await;
440 }
441
442 pub async fn set_heartbeat_nat_timeout(&self, timeout: Option<std::time::Duration>) {
444 self.wrapper.set_heartbeat_nat_timeout(timeout).await;
445 }
446
447 pub async fn heartbeat_effective_interval(&self) -> std::time::Duration {
449 self.wrapper.heartbeat_effective_interval().await
450 }
451
452 pub async fn update_parser(&self, parser: MessageParser) {
454 let mut pipeline = self.pipeline.lock().await;
455 *pipeline = MessagePipeline::new(parser);
456 }
457
458 pub async fn add_observer(&self, observer: Arc<dyn ConnectionObserver>) {
462 self.wrapper.add_observer(observer).await;
463 }
464}
465
466struct FlareObserver {
468 pipeline: Arc<Mutex<MessagePipeline>>,
469 listener: Arc<dyn MessageListener>,
470}
471
472impl ConnectionObserver for FlareObserver {
473 fn on_event(&self, event: &ConnectionEvent) {
474 match event {
475 ConnectionEvent::Connected => {
476 info!("[FlareClient] ✅ 已连接");
477 let listener = self.listener.clone();
479 crate::client::runtime::spawn_client_task(async move {
480 if let Err(e) = listener.on_connect().await {
481 error!("[FlareClient] on_connect 失败: {}", e);
482 }
483 });
484 }
485
486 ConnectionEvent::Disconnected(reason) => {
487 let reason_arc: Arc<str> = Arc::from(reason.as_str());
489 info!("[FlareClient] ❌ 连接断开: {}", reason_arc);
490 let listener = self.listener.clone();
491 crate::client::runtime::spawn_client_task(async move {
492 if let Err(e) = listener.on_disconnect(Some(&reason_arc)).await {
493 error!("[FlareClient] on_disconnect 失败: {}", e);
494 }
495 });
496 }
497
498 ConnectionEvent::Error(err) => {
499 let err_str = format!("{:?}", err);
502 let is_race_error = err_str.contains("Connection reset without closing handshake")
504 || (err_str.contains("ConnectionFailed")
505 && err_str.contains("WebSocket protocol error"));
506
507 let is_connection_lost = err_str.contains("connection lost")
509 || err_str.contains("connection closed")
510 || err_str.contains("Connection reset");
511
512 if is_race_error {
513 debug!(
515 "[FlareClient] 协议竞速:未选中协议连接已关闭(这是正常的,协议竞速会选择最快的协议)"
516 );
517 } else if is_connection_lost {
518 warn!("[FlareClient] 连接丢失: {:?}", err);
521 info!("[FlareClient] 💡 底层客户端将自动尝试重连(如果配置了重连)");
522 let listener = self.listener.clone();
523 let err_str_arc: Arc<str> = Arc::from(err_str.as_str());
525 crate::client::runtime::spawn_client_task(async move {
526 if let Err(e) = listener.on_error(&err_str_arc).await {
527 error!("[FlareClient] on_error 失败: {}", e);
528 }
529 });
530 } else {
531 warn!("[FlareClient] 连接错误: {:?}", err);
533 let listener = self.listener.clone();
534 let err_str_arc: Arc<str> = Arc::from(err_str.as_str());
536 crate::client::runtime::spawn_client_task(async move {
537 if let Err(e) = listener.on_error(&err_str_arc).await {
538 error!("[FlareClient] on_error 失败: {}", e);
539 }
540 });
541 }
542 }
543
544 ConnectionEvent::Message(data) => {
545 use crate::common::message::parser::PRE_NEGOTIATION_PARSER;
548 use crate::common::protocol::flare::core::commands::system_command::Type as SysType;
549
550 let pipeline = self.pipeline.clone();
551 let data = data.clone();
552 crate::client::runtime::spawn_client_task(async move {
553 if let Ok(frame) = PRE_NEGOTIATION_PARSER.parse(&data)
555 && let Some(cmd) = &frame.command
556 && let Some(CommandType::System(sys_cmd)) = &cmd.r#type
557 && sys_cmd.r#type == SysType::ConnectAck as i32
558 {
559 let format =
562 crate::common::protocol::SerializationFormat::try_from(sys_cmd.format)
563 .unwrap_or(crate::common::protocol::SerializationFormat::Json);
564 let compression =
565 crate::common::compression::CompressionAlgorithm::from_str(
566 &sys_cmd.compression,
567 )
568 .unwrap_or(crate::common::compression::CompressionAlgorithm::None);
569 let encryption = crate::common::encryption::EncryptionAlgorithm::from_str(
570 &sys_cmd.encryption,
571 )
572 .unwrap_or(crate::common::encryption::EncryptionAlgorithm::None);
573
574 {
576 let compression_clone = compression.clone();
577 let encryption_clone = encryption.clone();
578 let pipeline_guard = pipeline.lock().await;
579 let new_parser =
580 crate::common::MessageParser::new(format, compression, encryption);
581 pipeline_guard.update_parser(new_parser).await;
582 debug!(
583 "[FlareObserver] ✅ 已更新 MessagePipeline 的 parser: format={:?}, compression={:?}, encryption={:?}",
584 format, compression_clone, encryption_clone
585 );
586 }
587
588 let pipeline_guard = pipeline.lock().await;
590 match pipeline_guard.process_frame(&frame, None).await {
591 Ok(Some(_response_data)) => {
592 debug!(
593 "[FlareClient] 消息管道返回响应,但客户端无法自动发送,需要用户手动处理"
594 );
595 }
596 Ok(None) => {
597 debug!("[FlareClient] CONNECT_ACK 处理完成,无需响应");
598 }
599 Err(e) => {
600 error!("[FlareClient] CONNECT_ACK 处理失败: {}", e);
601 }
602 }
603 return;
604 }
605
606 let pipeline = pipeline.lock().await;
608 match pipeline.process_raw(&data, None).await {
609 Ok(Some(_response_data)) => {
610 debug!(
611 "[FlareClient] 消息管道返回响应,但客户端无法自动发送,需要用户手动处理"
612 );
613 }
616 Ok(None) => {
617 debug!("[FlareClient] 消息处理完成,无需响应");
618 }
619 Err(e) => {
620 error!("[FlareClient] 消息管道处理失败: {}", e);
621 }
622 }
623 });
624 }
625 }
626 }
627}
628
629struct ListenerProcessor {
631 listener: Arc<dyn MessageListener>,
632}
633
634#[async_trait]
635impl MessageProcessor for ListenerProcessor {
636 async fn process(&self, ctx: &MessageContext) -> Result<Option<Frame>> {
637 self.listener.on_message(&ctx.frame).await
638 }
639
640 fn name(&self) -> &str {
641 "ListenerProcessor"
642 }
643}