hyperlane_plugin_websocket/websocket/impl.rs
1use crate::*;
2
3/// Allows `String` to be used as a broadcast identifier.
4impl BroadcastTypeTrait for String {}
5
6/// Allows string slices to be used as broadcast identifiers.
7impl BroadcastTypeTrait for &str {}
8
9/// Allows `char` to be used as a broadcast identifier.
10impl BroadcastTypeTrait for char {}
11
12/// Allows `bool` to be used as a broadcast identifier.
13impl BroadcastTypeTrait for bool {}
14
15/// Allows `i8` to be used as a broadcast identifier.
16impl BroadcastTypeTrait for i8 {}
17
18/// Allows `i16` to be used as a broadcast identifier.
19impl BroadcastTypeTrait for i16 {}
20
21/// Allows `i32` to be used as a broadcast identifier.
22impl BroadcastTypeTrait for i32 {}
23
24/// Allows `i64` to be used as a broadcast identifier.
25impl BroadcastTypeTrait for i64 {}
26
27/// Allows `i128` to be used as a broadcast identifier.
28impl BroadcastTypeTrait for i128 {}
29
30/// Allows `isize` to be used as a broadcast identifier.
31impl BroadcastTypeTrait for isize {}
32
33/// Allows `u8` to be used as a broadcast identifier.
34impl BroadcastTypeTrait for u8 {}
35
36/// Allows `u16` to be used as a broadcast identifier.
37impl BroadcastTypeTrait for u16 {}
38
39/// Allows `u32` to be used as a broadcast identifier.
40impl BroadcastTypeTrait for u32 {}
41
42/// Allows `u64` to be used as a broadcast identifier.
43impl BroadcastTypeTrait for u64 {}
44
45/// Allows `u128` to be used as a broadcast identifier.
46impl BroadcastTypeTrait for u128 {}
47
48/// Allows `usize` to be used as a broadcast identifier.
49impl BroadcastTypeTrait for usize {}
50
51/// Allows `f32` to be used as a broadcast identifier.
52impl BroadcastTypeTrait for f32 {}
53
54/// Allows `f64` to be used as a broadcast identifier.
55impl BroadcastTypeTrait for f64 {}
56
57/// Allows `IpAddr` to be used as a broadcast identifier.
58impl BroadcastTypeTrait for IpAddr {}
59
60/// Allows `Ipv4Addr` to be used as a broadcast identifier.
61impl BroadcastTypeTrait for Ipv4Addr {}
62
63/// Allows `Ipv6Addr` to be used as a broadcast identifier.
64impl BroadcastTypeTrait for Ipv6Addr {}
65
66/// Allows `SocketAddr` to be used as a broadcast identifier.
67impl BroadcastTypeTrait for SocketAddr {}
68
69/// Allows `NonZeroU8` to be used as a broadcast identifier.
70impl BroadcastTypeTrait for NonZeroU8 {}
71
72/// Allows `NonZeroU16` to be used as a broadcast identifier.
73impl BroadcastTypeTrait for NonZeroU16 {}
74
75/// Allows `NonZeroU32` to be used as a broadcast identifier.
76impl BroadcastTypeTrait for NonZeroU32 {}
77
78/// Allows `NonZeroU64` to be used as a broadcast identifier.
79impl BroadcastTypeTrait for NonZeroU64 {}
80
81/// Allows `NonZeroU128` to be used as a broadcast identifier.
82impl BroadcastTypeTrait for NonZeroU128 {}
83
84/// Allows `NonZeroUsize` to be used as a broadcast identifier.
85impl BroadcastTypeTrait for NonZeroUsize {}
86
87/// Allows `NonZeroI8` to be used as a broadcast identifier.
88impl BroadcastTypeTrait for NonZeroI8 {}
89
90/// Allows `NonZeroI16` to be used as a broadcast identifier.
91impl BroadcastTypeTrait for NonZeroI16 {}
92
93/// Allows `NonZeroI32` to be used as a broadcast identifier.
94impl BroadcastTypeTrait for NonZeroI32 {}
95
96/// Allows `NonZeroI64` to be used as a broadcast identifier.
97impl BroadcastTypeTrait for NonZeroI64 {}
98
99/// Allows `NonZeroI128` to be used as a broadcast identifier.
100impl BroadcastTypeTrait for NonZeroI128 {}
101
102/// Allows `NonZeroIsize` to be used as a broadcast identifier.
103impl BroadcastTypeTrait for NonZeroIsize {}
104
105/// Allows `Infallible` to be used as a broadcast identifier.
106impl BroadcastTypeTrait for Infallible {}
107
108/// Allows references to `String` to be used as broadcast identifiers.
109impl BroadcastTypeTrait for &String {}
110
111/// Allows double references to string slices to be used as broadcast identifiers.
112impl BroadcastTypeTrait for &&str {}
113
114/// Allows references to `char` to be used as broadcast identifiers.
115impl BroadcastTypeTrait for &char {}
116
117/// Allows references to `bool` to be used as broadcast identifiers.
118impl BroadcastTypeTrait for &bool {}
119
120/// Allows references to `i8` to be used as broadcast identifiers.
121impl BroadcastTypeTrait for &i8 {}
122
123/// Allows references to `i16` to be used as broadcast identifiers.
124impl BroadcastTypeTrait for &i16 {}
125
126/// Allows references to `i32` to be used as broadcast identifiers.
127impl BroadcastTypeTrait for &i32 {}
128
129/// Allows references to `i64` to be used as broadcast identifiers.
130impl BroadcastTypeTrait for &i64 {}
131
132/// Allows references to `i128` to be used as broadcast identifiers.
133impl BroadcastTypeTrait for &i128 {}
134
135/// Allows references to `isize` to be used as broadcast identifiers.
136impl BroadcastTypeTrait for &isize {}
137
138/// Allows references to `u8` to be used as broadcast identifiers.
139impl BroadcastTypeTrait for &u8 {}
140
141/// Allows references to `u16` to be used as broadcast identifiers.
142impl BroadcastTypeTrait for &u16 {}
143
144/// Allows references to `u32` to be used as broadcast identifiers.
145impl BroadcastTypeTrait for &u32 {}
146
147/// Allows references to `u64` to be used as
148/// Implements `BroadcastTypeTrait` for `&u128`.
149///
150/// This allows references to `u128` to be used as a broadcast identifier.
151impl BroadcastTypeTrait for &u128 {}
152
153/// Implements `BroadcastTypeTrait` for `&usize`.
154///
155/// This allows references to `usize` to be used as a broadcast identifier.
156impl BroadcastTypeTrait for &usize {}
157
158/// Implements `BroadcastTypeTrait` for `&f32`.
159///
160/// This allows references to `f32` to be used as a broadcast identifier.
161impl BroadcastTypeTrait for &f32 {}
162
163/// Implements `BroadcastTypeTrait` for `&f64`.
164///
165/// This allows references to `f64` to be used as a broadcast identifier.
166impl BroadcastTypeTrait for &f64 {}
167
168/// Implements `BroadcastTypeTrait` for `&IpAddr`.
169///
170/// This allows references to `IpAddr` to be used as a broadcast identifier.
171impl BroadcastTypeTrait for &IpAddr {}
172
173/// Implements `BroadcastTypeTrait` for `&Ipv4Addr`.
174///
175/// This allows references to `Ipv4Addr` to be used as a broadcast identifier.
176impl BroadcastTypeTrait for &Ipv4Addr {}
177
178/// Implements `BroadcastTypeTrait` for `&Ipv6Addr`.
179///
180/// This allows references to `Ipv6Addr` to be used as a broadcast identifier.
181impl BroadcastTypeTrait for &Ipv6Addr {}
182
183/// Implements `BroadcastTypeTrait` for `&SocketAddr`.
184///
185/// This allows references to `SocketAddr` to be used as a broadcast identifier.
186impl BroadcastTypeTrait for &SocketAddr {}
187
188/// Implements `BroadcastTypeTrait` for `&NonZeroU8`.
189///
190/// This allows references to `NonZeroU8` to be used as a broadcast identifier.
191impl BroadcastTypeTrait for &NonZeroU8 {}
192
193/// Implements `BroadcastTypeTrait` for `&NonZeroU16`.
194///
195/// This allows references to `NonZeroU16` to be used as a broadcast identifier.
196impl BroadcastTypeTrait for &NonZeroU16 {}
197
198/// Implements `BroadcastTypeTrait` for `&NonZeroU32`.
199///
200/// This allows references to `NonZeroU32` to be used as a broadcast identifier.
201impl BroadcastTypeTrait for &NonZeroU32 {}
202
203/// Implements `BroadcastTypeTrait` for `&NonZeroU64`.
204///
205/// This allows references to `NonZeroU64` to be used as a broadcast identifier.
206impl BroadcastTypeTrait for &NonZeroU64 {}
207
208/// Implements `BroadcastTypeTrait` for `&NonZeroU128`.
209///
210/// This allows references to `NonZeroU128` to be used as a broadcast identifier.
211impl BroadcastTypeTrait for &NonZeroU128 {}
212
213/// Implements `BroadcastTypeTrait` for `&NonZeroUsize`.
214///
215/// This allows references to `NonZeroUsize` to be used as a broadcast identifier.
216impl BroadcastTypeTrait for &NonZeroUsize {}
217
218/// Implements `BroadcastTypeTrait` for `&NonZeroI8`.
219///
220/// This allows references to `NonZeroI8` to be used as a broadcast identifier.
221impl BroadcastTypeTrait for &NonZeroI8 {}
222
223/// Implements `BroadcastTypeTrait` for `&NonZeroI16`.
224///
225/// This allows references to `NonZeroI16` to be used as a broadcast identifier.
226impl BroadcastTypeTrait for &NonZeroI16 {}
227
228/// Implements `BroadcastTypeTrait` for `&NonZeroI32`.
229///
230/// This allows references to `NonZeroI32` to be used as a broadcast identifier.
231impl BroadcastTypeTrait for &NonZeroI32 {}
232
233/// Implements `BroadcastTypeTrait` for `&NonZeroI64`.
234///
235/// This allows references to `NonZeroI64` to be used as a broadcast identifier.
236impl BroadcastTypeTrait for &NonZeroI64 {}
237
238/// Implements `BroadcastTypeTrait` for `&NonZeroI128`.
239///
240/// This allows references to `NonZeroI128` to be used as a broadcast identifier.
241impl BroadcastTypeTrait for &NonZeroI128 {}
242
243/// Implements `BroadcastTypeTrait` for `&NonZeroIsize`.
244///
245/// This allows references to `NonZeroIsize` to be used as a broadcast identifier.
246impl BroadcastTypeTrait for &NonZeroIsize {}
247
248/// Implements `BroadcastTypeTrait` for `&Infallible`.
249///
250/// This allows references to `Infallible` to be used as a broadcast identifier.
251impl BroadcastTypeTrait for &Infallible {}
252
253/// Implements the `Default` trait for `BroadcastType`.
254///
255/// The default value is `BroadcastType::Unknown`.
256///
257/// # Type Parameters
258///
259/// - `B`: The type parameter for `BroadcastType`, which must implement `BroadcastTypeTrait`.
260impl<B: BroadcastTypeTrait> Default for BroadcastType<B> {
261 #[inline(always)]
262 fn default() -> Self {
263 BroadcastType::Unknown
264 }
265}
266
267impl<B: BroadcastTypeTrait> BroadcastType<B> {
268 /// Generates a unique key string for a given broadcast type.
269 ///
270 /// For point-to-point types, the keys are sorted to ensure consistent key generation
271 /// regardless of the order of the input keys.
272 ///
273 /// # Arguments
274 ///
275 /// - `BroadcastType<B>` - The broadcast type for which to generate the key.
276 ///
277 /// # Returns
278 ///
279 /// - `String` - The unique key string for the broadcast type.
280 #[inline(always)]
281 pub fn get_key(broadcast_type: BroadcastType<B>) -> String {
282 match broadcast_type {
283 BroadcastType::PointToPoint(key1, key2) => {
284 let (first_key, second_key) = if key1 <= key2 {
285 (key1, key2)
286 } else {
287 (key2, key1)
288 };
289 format!(
290 "{}-{}-{}",
291 POINT_TO_POINT_KEY,
292 first_key.to_string(),
293 second_key.to_string()
294 )
295 }
296 BroadcastType::PointToGroup(key) => {
297 format!("{}-{}", POINT_TO_GROUP_KEY, key.to_string())
298 }
299 BroadcastType::Unknown => String::new(),
300 }
301 }
302}
303
304/// Implements the `Default` trait for `WebSocketConfig`.
305///
306/// Provides a default configuration for WebSocket connections, including
307/// default hook types that do nothing.
308///
309/// # Type Parameters
310///
311/// - `B`: The type parameter for `WebSocketConfig`, which must implement `BroadcastTypeTrait`.
312impl<B: BroadcastTypeTrait> Default for WebSocketConfig<B> {
313 #[inline(always)]
314 fn default() -> Self {
315 let default_hook: ServerHookHandler = Arc::new(|_ctx| Box::pin(async {}));
316 Self {
317 context: Context::default(),
318 request_config: RequestConfig::default(),
319 capacity: DEFAULT_BROADCAST_SENDER_CAPACITY,
320 broadcast_type: BroadcastType::default(),
321 connected_hook: default_hook.clone(),
322 request_hook: default_hook.clone(),
323 sended_hook: default_hook.clone(),
324 closed_hook: default_hook,
325 }
326 }
327}
328
329impl<B: BroadcastTypeTrait> WebSocketConfig<B> {
330 /// Creates a new WebSocket configuration with default values.
331 ///
332 /// # Returns
333 ///
334 /// - `WebSocketConfig<B>` - A new WebSocket configuration instance.
335 #[inline(always)]
336 pub fn new() -> Self {
337 Self::default()
338 }
339}
340
341impl<B: BroadcastTypeTrait> WebSocketConfig<B> {
342 /// Sets the request configuration for the WebSocket connection.
343 ///
344 /// # Arguments
345 ///
346 /// - `RequestConfig` - The request configuration to use for this WebSocket.
347 ///
348 /// # Returns
349 ///
350 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
351 #[inline(always)]
352 pub fn set_request_config(mut self, request_config: RequestConfig) -> Self {
353 self.request_config = request_config;
354 self
355 }
356
357 /// Sets the capacity for the broadcast sender.
358 ///
359 /// # Arguments
360 ///
361 /// - `Capacity` - The desired capacity.
362 ///
363 /// # Returns
364 ///
365 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
366 #[inline(always)]
367 pub fn set_capacity(mut self, capacity: Capacity) -> Self {
368 self.capacity = capacity;
369 self
370 }
371
372 /// Sets the context for the WebSocket connection.
373 ///
374 /// # Arguments
375 ///
376 /// - `Context` - The context object to associate with the WebSocket.
377 ///
378 /// # Returns
379 ///
380 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
381 #[inline(always)]
382 pub fn set_context(mut self, context: Context) -> Self {
383 self.context = context;
384 self
385 }
386
387 /// Sets the broadcast type for the WebSocket connection.
388 ///
389 /// # Arguments
390 ///
391 /// - `BroadcastType<B>` - The broadcast type to use for this WebSocket.
392 ///
393 /// # Returns
394 ///
395 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
396 #[inline(always)]
397 pub fn set_broadcast_type(mut self, broadcast_type: BroadcastType<B>) -> Self {
398 self.broadcast_type = broadcast_type;
399 self
400 }
401
402 /// Retrieves a reference to the context associated with this configuration.
403 ///
404 /// # Returns
405 ///
406 /// - `&Context` - A reference to the context object.
407 #[inline(always)]
408 pub fn get_context(&self) -> &Context {
409 &self.context
410 }
411
412 /// Retrieves the request configuration for this WebSocket.
413 ///
414 /// # Returns
415 ///
416 /// - `RequestConfig` - The request configuration object.
417 #[inline(always)]
418 pub fn get_request_config(&self) -> RequestConfig {
419 self.request_config
420 }
421
422 /// Retrieves the capacity configured for the broadcast sender.
423 ///
424 /// # Returns
425 ///
426 /// - `Capacity` - The capacity.
427 #[inline(always)]
428 pub fn get_capacity(&self) -> Capacity {
429 self.capacity
430 }
431
432 /// Retrieves a reference to the broadcast type configured for this WebSocket.
433 ///
434 /// # Returns
435 ///
436 /// - `&BroadcastType<B>` - A reference to the broadcast type object.
437 #[inline(always)]
438 pub fn get_broadcast_type(&self) -> &BroadcastType<B> {
439 &self.broadcast_type
440 }
441
442 /// Sets the connected hook handler.
443 ///
444 /// This hook is executed when the WebSocket connection is established.
445 ///
446 /// # Type Parameters
447 ///
448 /// - `S`: The hook type, which must implement `ServerHook`.
449 ///
450 /// # Returns
451 ///
452 /// The modified `WebSocketConfig` instance.
453 ///
454 /// # Examples
455 ///
456 /// ```rust,ignore
457 /// struct MyConnectedHook;
458 /// impl ServerHook for MyConnectedHook {
459 /// async fn new(_ctx: &Context) -> Self { Self }
460 /// async fn handle(self, ctx: &Context) { /* ... */ }
461 /// }
462 ///
463 /// let config = WebSocketConfig::new()
464 /// .set_connected_hook::<MyConnectedHook>();
465 /// ```
466 #[inline(always)]
467 pub fn set_connected_hook<S>(mut self) -> Self
468 where
469 S: ServerHook,
470 {
471 self.connected_hook = server_hook_factory::<S>();
472 self
473 }
474
475 /// Sets the request hook handler.
476 ///
477 /// This hook is executed when a new request is received on the WebSocket.
478 ///
479 /// # Type Parameters
480 ///
481 /// - `S`: The hook type, which must implement `ServerHook`.
482 ///
483 /// # Returns
484 ///
485 /// The modified `WebSocketConfig` instance.
486 ///
487 /// # Examples
488 ///
489 /// ```rust,ignore
490 /// struct MyRequestHook;
491 /// impl ServerHook for MyRequestHook {
492 /// async fn new(_ctx: &Context) -> Self { Self }
493 /// async fn handle(self, ctx: &Context) { /* ... */ }
494 /// }
495 ///
496 /// let config = WebSocketConfig::new()
497 /// .set_request_hook::<MyRequestHook>();
498 /// ```
499 #[inline(always)]
500 pub fn set_request_hook<S>(mut self) -> Self
501 where
502 S: ServerHook,
503 {
504 self.request_hook = server_hook_factory::<S>();
505 self
506 }
507
508 /// Sets the sended hook handler.
509 ///
510 /// This hook is executed after a message has been successfully sent over the WebSocket.
511 ///
512 /// # Type Parameters
513 ///
514 /// - `S`: The hook type, which must implement `ServerHook`.
515 ///
516 /// # Returns
517 ///
518 /// The modified `WebSocketConfig` instance.
519 ///
520 /// # Examples
521 ///
522 /// ```rust,ignore
523 /// struct MySendedHook;
524 /// impl ServerHook for MySendedHook {
525 /// async fn new(_ctx: &Context) -> Self { Self }
526 /// async fn handle(self, ctx: &Context) { /* ... */ }
527 /// }
528 ///
529 /// let config = WebSocketConfig::new()
530 /// .set_sended_hook::<MySendedHook>();
531 /// ```
532 #[inline(always)]
533 pub fn set_sended_hook<S>(mut self) -> Self
534 where
535 S: ServerHook,
536 {
537 self.sended_hook = server_hook_factory::<S>();
538 self
539 }
540
541 /// Sets the closed hook handler.
542 ///
543 /// This hook is executed when the WebSocket connection is closed.
544 ///
545 /// # Type Parameters
546 ///
547 /// - `S`: The hook type, which must implement `ServerHook`.
548 ///
549 /// # Returns
550 ///
551 /// The modified `WebSocketConfig` instance.
552 ///
553 /// # Examples
554 ///
555 /// ```rust,ignore
556 /// struct MyClosedHook;
557 /// impl ServerHook for MyClosedHook {
558 /// async fn new(_ctx: &Context) -> Self { Self }
559 /// async fn handle(self, ctx: &Context) { /* ... */ }
560 /// }
561 ///
562 /// let config = WebSocketConfig::new()
563 /// .set_closed_hook::<MyClosedHook>();
564 /// ```
565 #[inline(always)]
566 pub fn set_closed_hook<S>(mut self) -> Self
567 where
568 S: ServerHook,
569 {
570 self.closed_hook = server_hook_factory::<S>();
571 self
572 }
573
574 /// Retrieves a reference to the connected hook handler.
575 ///
576 /// # Returns
577 ///
578 /// - `&ServerHookHandler` - A reference to the connected hook handler.
579 #[inline(always)]
580 pub fn get_connected_hook(&self) -> &ServerHookHandler {
581 &self.connected_hook
582 }
583
584 /// Retrieves a reference to the request hook handler.
585 ///
586 /// # Returns
587 ///
588 /// - `&ServerHookHandler` - A reference to the request hook handler.
589 #[inline(always)]
590 pub fn get_request_hook(&self) -> &ServerHookHandler {
591 &self.request_hook
592 }
593
594 /// Retrieves a reference to the sended hook handler.
595 ///
596 /// # Returns
597 ///
598 /// - `&ServerHookHandler` - A reference to the sended hook handler.
599 #[inline(always)]
600 pub fn get_sended_hook(&self) -> &ServerHookHandler {
601 &self.sended_hook
602 }
603
604 /// Retrieves a reference to the closed hook handler.
605 ///
606 /// # Returns
607 ///
608 /// - `&ServerHookHandler` - A reference to the closed hook handler.
609 #[inline(always)]
610 pub fn get_closed_hook(&self) -> &ServerHookHandler {
611 &self.closed_hook
612 }
613}
614
615impl WebSocket {
616 /// Creates a new WebSocket instance.
617 ///
618 /// Initializes with a default broadcast map.
619 ///
620 /// # Returns
621 ///
622 /// - `WebSocket` - A new WebSocket instance.
623 #[inline(always)]
624 pub fn new() -> Self {
625 Self::default()
626 }
627
628 /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
629 ///
630 /// # Type Parameters
631 ///
632 /// - `B`: The type implementing `BroadcastTypeTrait`.
633 ///
634 /// # Arguments
635 ///
636 /// - `BroadcastType<B>` - The broadcast type to subscribe to.
637 /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
638 ///
639 /// # Returns
640 ///
641 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
642 #[inline(always)]
643 fn subscribe_unwrap_or_insert<B: BroadcastTypeTrait>(
644 &self,
645 broadcast_type: BroadcastType<B>,
646 capacity: Capacity,
647 ) -> BroadcastMapReceiver<Vec<u8>> {
648 let key: String = BroadcastType::get_key(broadcast_type);
649 self.broadcast_map.subscribe_or_insert(&key, capacity)
650 }
651
652 /// Subscribes to a point-to-point broadcast.
653 ///
654 /// # Type Parameters
655 ///
656 /// - `B`: The type implementing `BroadcastTypeTrait`.
657 ///
658 /// # Arguments
659 ///
660 /// - `&B` - The first identifier for the point-to-point communication.
661 /// - `&B` - The second identifier for the point-to-point communication.
662 /// - `Capacity` - The capacity for the broadcast sender.
663 ///
664 /// # Returns
665 ///
666 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
667 #[inline(always)]
668 fn point_to_point<B: BroadcastTypeTrait>(
669 &self,
670 key1: &B,
671 key2: &B,
672 capacity: Capacity,
673 ) -> BroadcastMapReceiver<Vec<u8>> {
674 self.subscribe_unwrap_or_insert(
675 BroadcastType::PointToPoint(key1.clone(), key2.clone()),
676 capacity,
677 )
678 }
679
680 /// Subscribes to a point-to-group broadcast.
681 ///
682 /// # Type Parameters
683 ///
684 /// - `B`: The type implementing `BroadcastTypeTrait`.
685 ///
686 /// # Arguments
687 ///
688 /// - `&B` - The identifier for the group.
689 /// - `Capacity` - The capacity for the broadcast sender.
690 ///
691 /// # Returns
692 ///
693 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
694 #[inline(always)]
695 fn point_to_group<B: BroadcastTypeTrait>(
696 &self,
697 key: &B,
698 capacity: Capacity,
699 ) -> BroadcastMapReceiver<Vec<u8>> {
700 self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
701 }
702
703 /// Retrieves the current receiver count for a given broadcast type.
704 ///
705 /// # Type Parameters
706 ///
707 /// - `B`: The type implementing `BroadcastTypeTrait`.
708 ///
709 /// # Arguments
710 ///
711 /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
712 ///
713 /// # Returns
714 ///
715 /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
716 #[inline(always)]
717 pub fn receiver_count<B: BroadcastTypeTrait>(
718 &self,
719 broadcast_type: BroadcastType<B>,
720 ) -> ReceiverCount {
721 let key: String = BroadcastType::get_key(broadcast_type);
722 self.broadcast_map.receiver_count(&key).unwrap_or(0)
723 }
724
725 /// Calculates the receiver count before a connection is established.
726 ///
727 /// Ensures the count does not exceed the maximum allowed value minus one.
728 ///
729 /// # Type Parameters
730 ///
731 /// - `B`: The type implementing `BroadcastTypeTrait`.
732 ///
733 /// # Arguments
734 ///
735 /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
736 ///
737 /// # Returns
738 ///
739 /// - `ReceiverCount` - The receiver count after the connection is established.
740 #[inline(always)]
741 pub fn receiver_count_before_connected<B: BroadcastTypeTrait>(
742 &self,
743 broadcast_type: BroadcastType<B>,
744 ) -> ReceiverCount {
745 let count: ReceiverCount = self.receiver_count(broadcast_type);
746 count.clamp(0, ReceiverCount::MAX - 1) + 1
747 }
748
749 /// Calculates the receiver count after a connection is closed.
750 ///
751 /// Ensures the count does not go below 0.
752 ///
753 /// # Type Parameters
754 ///
755 /// - `B`: The type implementing `BroadcastTypeTrait`.
756 ///
757 /// # Arguments
758 ///
759 /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
760 ///
761 /// # Returns
762 ///
763 /// - `ReceiverCount` - The receiver count after the connection is closed.
764 #[inline(always)]
765 pub fn receiver_count_after_closed<B: BroadcastTypeTrait>(
766 &self,
767 broadcast_type: BroadcastType<B>,
768 ) -> ReceiverCount {
769 let count: ReceiverCount = self.receiver_count(broadcast_type);
770 count.clamp(1, ReceiverCount::MAX) - 1
771 }
772
773 /// Sends data to all active receivers for a given broadcast type.
774 ///
775 /// # Type Parameters
776 ///
777 /// - `T`: The type of data to send, which must be convertible to `Vec<u8>`.
778 /// - `B`: The type implementing `BroadcastTypeTrait`.
779 ///
780 /// # Arguments
781 ///
782 /// - `BroadcastType<B>` - The broadcast type to which to send the data.
783 /// - `T` - The data to send.
784 ///
785 /// # Returns
786 ///
787 /// - `BroadcastMapSendResult<Vec<u8>>` - A result indicating the success or failure of the send operation.
788 #[inline(always)]
789 pub fn send<T, B>(
790 &self,
791 broadcast_type: BroadcastType<B>,
792 data: T,
793 ) -> BroadcastMapSendResult<Vec<u8>>
794 where
795 T: Into<Vec<u8>>,
796 B: BroadcastTypeTrait,
797 {
798 let key: String = BroadcastType::get_key(broadcast_type);
799 self.broadcast_map.send(&key, data.into())
800 }
801
802 /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
803 ///
804 /// This asynchronous function continuously monitors for new WebSocket requests
805 /// and incoming broadcast messages, processing them according to the configured hooks.
806 ///
807 /// # Type Parameters
808 ///
809 /// - `B`: The type implementing `BroadcastTypeTrait`.
810 ///
811 /// # Arguments
812 ///
813 /// - `WebSocketConfig<B>` - The WebSocket configuration containing the configuration for this WebSocket instance.
814 ///
815 /// # Panics
816 ///
817 /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
818 /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
819 pub async fn run<B: BroadcastTypeTrait>(&self, config: WebSocketConfig<B>) {
820 let ctx: Context = config.get_context().clone();
821 if ctx.to_string() == Context::default().to_string() {
822 panic!("Context must be set");
823 }
824 let request_config: RequestConfig = config.get_request_config();
825 let capacity: Capacity = config.get_capacity();
826 let broadcast_type: BroadcastType<B> = config.get_broadcast_type().clone();
827 let mut receiver: Receiver<Vec<u8>> = match &broadcast_type {
828 BroadcastType::PointToPoint(key1, key2) => self.point_to_point(key1, key2, capacity),
829 BroadcastType::PointToGroup(key) => self.point_to_group(key, capacity),
830 BroadcastType::Unknown => panic!("BroadcastType must be PointToPoint or PointToGroup"),
831 };
832 let key: String = BroadcastType::get_key(broadcast_type);
833 config.get_connected_hook()(&ctx).await;
834 let result_handle = || async {
835 ctx.aborted().await;
836 ctx.closed().await;
837 };
838 loop {
839 tokio::select! {
840 request_res = ctx.ws_from_stream(request_config) => {
841 if request_res.is_ok() {
842 config.get_request_hook()(&ctx).await;
843 } else {
844 config.get_closed_hook()(&ctx).await;
845 }
846 if ctx.get_aborted().await {
847 continue;
848 }
849 if ctx.get_closed().await {
850 break;
851 }
852 let body: ResponseBody = ctx.get_response_body().await;
853 let is_err: bool = self.broadcast_map.send(&key, body).is_err();
854 config.get_sended_hook()(&ctx).await;
855 if is_err || ctx.get_closed().await{
856 break;
857 }
858 },
859 msg_res = receiver.recv() => {
860 if let Ok(msg) = &msg_res {
861 let frame_list: Vec<ResponseBody> = WebSocketFrame::create_frame_list(msg);
862 if ctx.send_body_list_with_data(&frame_list).await.is_ok() {
863 continue;
864 }
865 }
866 break;
867 }
868 }
869 }
870 result_handle().await;
871 }
872}