hyperlane_plugin_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/// - `BroadcastTypeTrait`: The type parameter for `BroadcastType`, which must implement `BroadcastTypeTrait`.
260impl<B> Default for BroadcastType<B>
261where
262 B: BroadcastTypeTrait,
263{
264 #[inline(always)]
265 fn default() -> Self {
266 BroadcastType::Unknown
267 }
268}
269
270impl<B> BroadcastType<B>
271where
272 B: BroadcastTypeTrait,
273{
274 /// Generates a unique key string for a given broadcast type.
275 ///
276 /// For point-to-point types, the keys are sorted to ensure consistent key generation
277 /// regardless of the order of the input keys.
278 ///
279 /// # Arguments
280 ///
281 /// - `BroadcastType<B>` - The broadcast type for which to generate the key.
282 ///
283 /// # Returns
284 ///
285 /// - `String` - The unique key string for the broadcast type.
286 #[inline(always)]
287 pub fn get_key(broadcast_type: BroadcastType<B>) -> String {
288 match broadcast_type {
289 BroadcastType::PointToPoint(key1, key2) => {
290 let (first_key, second_key) = if key1 <= key2 {
291 (key1, key2)
292 } else {
293 (key2, key1)
294 };
295 format!(
296 "{}-{}-{}",
297 POINT_TO_POINT_KEY,
298 first_key.to_string(),
299 second_key.to_string()
300 )
301 }
302 BroadcastType::PointToGroup(key) => {
303 format!("{}-{}", POINT_TO_GROUP_KEY, key.to_string())
304 }
305 BroadcastType::Unknown => String::new(),
306 }
307 }
308}
309
310/// Implements the `Default` trait for `WebSocketConfig`.
311///
312/// Provides a default configuration for WebSocket connections, including
313/// default hook types that do nothing.
314///
315/// # Type Parameters
316///
317/// - `BroadcastTypeTrait`: The type parameter for `WebSocketConfig`, which must implement `BroadcastTypeTrait`.
318impl<B> Default for WebSocketConfig<B>
319where
320 B: BroadcastTypeTrait,
321{
322 #[inline(always)]
323 fn default() -> Self {
324 let default_hook: ServerHookHandler = Arc::new(|_ctx| Box::pin(async {}));
325 Self {
326 context: Context::default(),
327 capacity: DEFAULT_BROADCAST_SENDER_CAPACITY,
328 broadcast_type: BroadcastType::default(),
329 connected_hook: default_hook.clone(),
330 request_hook: default_hook.clone(),
331 sended_hook: default_hook.clone(),
332 closed_hook: default_hook,
333 }
334 }
335}
336
337impl<B> WebSocketConfig<B>
338where
339 B: BroadcastTypeTrait,
340{
341 /// Creates a new WebSocket configuration with default values.
342 ///
343 /// # Returns
344 ///
345 /// - `WebSocketConfig<B>` - A new WebSocket configuration instance.
346 #[inline(always)]
347 pub fn new() -> Self {
348 Self::default()
349 }
350}
351
352impl<B> WebSocketConfig<B>
353where
354 B: BroadcastTypeTrait,
355{
356 /// Sets the capacity for the broadcast sender.
357 ///
358 /// # Arguments
359 ///
360 /// - `Capacity` - The desired capacity.
361 ///
362 /// # Returns
363 ///
364 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
365 #[inline(always)]
366 pub fn set_capacity(mut self, capacity: Capacity) -> Self {
367 self.capacity = capacity;
368 self
369 }
370
371 /// Sets the context for the WebSocket connection.
372 ///
373 /// # Arguments
374 ///
375 /// - `Context` - The context object to associate with the WebSocket.
376 ///
377 /// # Returns
378 ///
379 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
380 #[inline(always)]
381 pub fn set_context(mut self, context: Context) -> Self {
382 self.context = context;
383 self
384 }
385
386 /// Sets the broadcast type for the WebSocket connection.
387 ///
388 /// # Arguments
389 ///
390 /// - `BroadcastType<B>` - The broadcast type to use for this WebSocket.
391 ///
392 /// # Returns
393 ///
394 /// - `WebSocketConfig<B>` - The modified WebSocket configuration instance.
395 #[inline(always)]
396 pub fn set_broadcast_type(mut self, broadcast_type: BroadcastType<B>) -> Self {
397 self.broadcast_type = broadcast_type;
398 self
399 }
400
401 /// Retrieves a reference to the context associated with this configuration.
402 ///
403 /// # Returns
404 ///
405 /// - `&Context` - A reference to the context object.
406 #[inline(always)]
407 pub fn get_context(&self) -> &Context {
408 &self.context
409 }
410
411 /// Retrieves the capacity configured for the broadcast sender.
412 ///
413 /// # Returns
414 ///
415 /// - `Capacity` - The capacity.
416 #[inline(always)]
417 pub fn get_capacity(&self) -> Capacity {
418 self.capacity
419 }
420
421 /// Retrieves a reference to the broadcast type configured for this WebSocket.
422 ///
423 /// # Returns
424 ///
425 /// - `&BroadcastType<B>` - A reference to the broadcast type object.
426 #[inline(always)]
427 pub fn get_broadcast_type(&self) -> &BroadcastType<B> {
428 &self.broadcast_type
429 }
430
431 /// Sets the connected hook handler.
432 ///
433 /// This hook is executed when the WebSocket connection is established.
434 ///
435 /// # Type Parameters
436 ///
437 /// - `S`: The hook type, which must implement `ServerHook`.
438 ///
439 /// # Returns
440 ///
441 /// The modified `WebSocketConfig` instance.
442 ///
443 /// # Examples
444 ///
445 /// ```rust,ignore
446 /// struct MyConnectedHook;
447 /// impl ServerHook for MyConnectedHook {
448 /// async fn new(_ctx: &Context) -> Self { Self }
449 /// async fn handle(self, ctx: &Context) { /* ... */ }
450 /// }
451 ///
452 /// let config = WebSocketConfig::new()
453 /// .set_connected_hook::<MyConnectedHook>();
454 /// ```
455 #[inline(always)]
456 pub fn set_connected_hook<S>(mut self) -> Self
457 where
458 S: ServerHook,
459 {
460 self.connected_hook = server_hook_factory::<S>();
461 self
462 }
463
464 /// Sets the request hook handler.
465 ///
466 /// This hook is executed when a new request is received on the WebSocket.
467 ///
468 /// # Type Parameters
469 ///
470 /// - `S`: The hook type, which must implement `ServerHook`.
471 ///
472 /// # Returns
473 ///
474 /// The modified `WebSocketConfig` instance.
475 ///
476 /// # Examples
477 ///
478 /// ```rust,ignore
479 /// struct MyRequestHook;
480 /// impl ServerHook for MyRequestHook {
481 /// async fn new(_ctx: &Context) -> Self { Self }
482 /// async fn handle(self, ctx: &Context) { /* ... */ }
483 /// }
484 ///
485 /// let config = WebSocketConfig::new()
486 /// .set_request_hook::<MyRequestHook>();
487 /// ```
488 #[inline(always)]
489 pub fn set_request_hook<S>(mut self) -> Self
490 where
491 S: ServerHook,
492 {
493 self.request_hook = server_hook_factory::<S>();
494 self
495 }
496
497 /// Sets the sended hook handler.
498 ///
499 /// This hook is executed after a message has been successfully sent over the WebSocket.
500 ///
501 /// # Type Parameters
502 ///
503 /// - `S`: The hook type, which must implement `ServerHook`.
504 ///
505 /// # Returns
506 ///
507 /// The modified `WebSocketConfig` instance.
508 ///
509 /// # Examples
510 ///
511 /// ```rust,ignore
512 /// struct MySendedHook;
513 /// impl ServerHook for MySendedHook {
514 /// async fn new(_ctx: &Context) -> Self { Self }
515 /// async fn handle(self, ctx: &Context) { /* ... */ }
516 /// }
517 ///
518 /// let config = WebSocketConfig::new()
519 /// .set_sended_hook::<MySendedHook>();
520 /// ```
521 #[inline(always)]
522 pub fn set_sended_hook<S>(mut self) -> Self
523 where
524 S: ServerHook,
525 {
526 self.sended_hook = server_hook_factory::<S>();
527 self
528 }
529
530 /// Sets the closed hook handler.
531 ///
532 /// This hook is executed when the WebSocket connection is closed.
533 ///
534 /// # Type Parameters
535 ///
536 /// - `S`: The hook type, which must implement `ServerHook`.
537 ///
538 /// # Returns
539 ///
540 /// The modified `WebSocketConfig` instance.
541 ///
542 /// # Examples
543 ///
544 /// ```rust,ignore
545 /// struct MyClosedHook;
546 /// impl ServerHook for MyClosedHook {
547 /// async fn new(_ctx: &Context) -> Self { Self }
548 /// async fn handle(self, ctx: &Context) { /* ... */ }
549 /// }
550 ///
551 /// let config = WebSocketConfig::new()
552 /// .set_closed_hook::<MyClosedHook>();
553 /// ```
554 #[inline(always)]
555 pub fn set_closed_hook<S>(mut self) -> Self
556 where
557 S: ServerHook,
558 {
559 self.closed_hook = server_hook_factory::<S>();
560 self
561 }
562
563 /// Retrieves a reference to the connected hook handler.
564 ///
565 /// # Returns
566 ///
567 /// - `&ServerHookHandler` - A reference to the connected hook handler.
568 #[inline(always)]
569 pub fn get_connected_hook(&self) -> &ServerHookHandler {
570 &self.connected_hook
571 }
572
573 /// Retrieves a reference to the request hook handler.
574 ///
575 /// # Returns
576 ///
577 /// - `&ServerHookHandler` - A reference to the request hook handler.
578 #[inline(always)]
579 pub fn get_request_hook(&self) -> &ServerHookHandler {
580 &self.request_hook
581 }
582
583 /// Retrieves a reference to the sended hook handler.
584 ///
585 /// # Returns
586 ///
587 /// - `&ServerHookHandler` - A reference to the sended hook handler.
588 #[inline(always)]
589 pub fn get_sended_hook(&self) -> &ServerHookHandler {
590 &self.sended_hook
591 }
592
593 /// Retrieves a reference to the closed hook handler.
594 ///
595 /// # Returns
596 ///
597 /// - `&ServerHookHandler` - A reference to the closed hook handler.
598 #[inline(always)]
599 pub fn get_closed_hook(&self) -> &ServerHookHandler {
600 &self.closed_hook
601 }
602}
603
604impl WebSocket {
605 /// Creates a new WebSocket instance.
606 ///
607 /// Initializes with a default broadcast map.
608 ///
609 /// # Returns
610 ///
611 /// - `WebSocket` - A new WebSocket instance.
612 #[inline(always)]
613 pub fn new() -> Self {
614 Self::default()
615 }
616
617 /// Subscribes to a broadcast type or inserts a new one if it doesn't exist.
618 ///
619 /// # Type Parameters
620 ///
621 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
622 ///
623 /// # Arguments
624 ///
625 /// - `BroadcastType<B>` - The broadcast type to subscribe to.
626 /// - `Capacity` - The capacity for the broadcast sender if a new one is inserted.
627 ///
628 /// # Returns
629 ///
630 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the specified broadcast type.
631 #[inline(always)]
632 fn subscribe_unwrap_or_insert<B>(
633 &self,
634 broadcast_type: BroadcastType<B>,
635 capacity: Capacity,
636 ) -> BroadcastMapReceiver<Vec<u8>>
637 where
638 B: BroadcastTypeTrait,
639 {
640 let key: String = BroadcastType::get_key(broadcast_type);
641 self.broadcast_map.subscribe_or_insert(&key, capacity)
642 }
643
644 /// Subscribes to a point-to-point broadcast.
645 ///
646 /// # Type Parameters
647 ///
648 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
649 ///
650 /// # Arguments
651 ///
652 /// - `&BroadcastTypeTrait` - The first identifier for the point-to-point communication.
653 /// - `&BroadcastTypeTrait` - The second identifier for the point-to-point communication.
654 /// - `Capacity` - The capacity for the broadcast sender.
655 ///
656 /// # Returns
657 ///
658 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-point broadcast.
659 #[inline(always)]
660 fn point_to_point<B>(
661 &self,
662 key1: &B,
663 key2: &B,
664 capacity: Capacity,
665 ) -> BroadcastMapReceiver<Vec<u8>>
666 where
667 B: BroadcastTypeTrait,
668 {
669 self.subscribe_unwrap_or_insert(
670 BroadcastType::PointToPoint(key1.clone(), key2.clone()),
671 capacity,
672 )
673 }
674
675 /// Subscribes to a point-to-group broadcast.
676 ///
677 /// # Type Parameters
678 ///
679 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
680 ///
681 /// # Arguments
682 ///
683 /// - `&BroadcastTypeTrait` - The identifier for the group.
684 /// - `Capacity` - The capacity for the broadcast sender.
685 ///
686 /// # Returns
687 ///
688 /// - `BroadcastMapReceiver<Vec<u8>>` - A broadcast map receiver for the point-to-group broadcast.
689 #[inline(always)]
690 fn point_to_group<B>(&self, key: &B, capacity: Capacity) -> BroadcastMapReceiver<Vec<u8>>
691 where
692 B: BroadcastTypeTrait,
693 {
694 self.subscribe_unwrap_or_insert(BroadcastType::PointToGroup(key.clone()), capacity)
695 }
696
697 /// Retrieves the current receiver count for a given broadcast type.
698 ///
699 /// # Type Parameters
700 ///
701 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
702 ///
703 /// # Arguments
704 ///
705 /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
706 ///
707 /// # Returns
708 ///
709 /// - `ReceiverCount` - The number of active receivers for the broadcast type, or 0 if not found.
710 #[inline(always)]
711 pub fn receiver_count<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
712 where
713 B: BroadcastTypeTrait,
714 {
715 let key: String = BroadcastType::get_key(broadcast_type);
716 self.broadcast_map.receiver_count(&key).unwrap_or(0)
717 }
718
719 /// Calculates the receiver count before a connection is established.
720 ///
721 /// Ensures the count does not exceed the maximum allowed value minus one.
722 ///
723 /// # Type Parameters
724 ///
725 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
726 ///
727 /// # Arguments
728 ///
729 /// - `BroadcastType<B>` - The broadcast type for which to get the receiver count.
730 ///
731 /// # Returns
732 ///
733 /// - `ReceiverCount` - The receiver count after the connection is established.
734 #[inline(always)]
735 pub fn receiver_count_before_connected<B>(
736 &self,
737 broadcast_type: BroadcastType<B>,
738 ) -> ReceiverCount
739 where
740 B: BroadcastTypeTrait,
741 {
742 let count: ReceiverCount = self.receiver_count(broadcast_type);
743 count.clamp(0, ReceiverCount::MAX - 1) + 1
744 }
745
746 /// Calculates the receiver count after a connection is closed.
747 ///
748 /// Ensures the count does not go below 0.
749 ///
750 /// # Type Parameters
751 ///
752 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
753 ///
754 /// # Arguments
755 ///
756 /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type for which to get the receiver count.
757 ///
758 /// # Returns
759 ///
760 /// - `ReceiverCount` - The receiver count after the connection is closed.
761 #[inline(always)]
762 pub fn receiver_count_after_closed<B>(&self, broadcast_type: BroadcastType<B>) -> ReceiverCount
763 where
764 B: BroadcastTypeTrait,
765 {
766 let count: ReceiverCount = self.receiver_count(broadcast_type);
767 count.clamp(1, ReceiverCount::MAX) - 1
768 }
769
770 /// Sends data to all active receivers for a given broadcast type.
771 ///
772 /// # Type Parameters
773 ///
774 /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
775 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
776 ///
777 /// # Arguments
778 ///
779 /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type to which to send the data.
780 /// - `Into<Vec<u8>>` - The data to send.
781 ///
782 /// # Returns
783 ///
784 /// - `Result<Option<ReceiverCount>, SendError<Vec<u8>>>` - A result indicating the success or failure of the send operation.
785 #[inline(always)]
786 pub fn try_send<T, B>(
787 &self,
788 broadcast_type: BroadcastType<B>,
789 data: T,
790 ) -> Result<Option<ReceiverCount>, SendError<Vec<u8>>>
791 where
792 T: Into<Vec<u8>>,
793 B: BroadcastTypeTrait,
794 {
795 let key: String = BroadcastType::get_key(broadcast_type);
796 self.broadcast_map.try_send(&key, data.into())
797 }
798
799 /// Sends data to all active receivers for a given broadcast type.
800 ///
801 /// This method panics if the send operation fails.
802 ///
803 /// # Type Parameters
804 ///
805 /// - `Into<Vec<u8>>`: The type of data to send, which must be convertible to `Vec<u8>`.
806 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
807 ///
808 /// # Arguments
809 ///
810 /// - `BroadcastType<BroadcastTypeTrait>` - The broadcast type to which to send the data.
811 /// - `Into<Vec<u8>>` - The data to send.
812 ///
813 /// # Returns
814 ///
815 /// - `Option<ReceiverCount>` - The receiver count if the send operation succeeds.
816 ///
817 /// # Panics
818 ///
819 /// Panics if the send operation fails.
820 #[inline(always)]
821 pub fn send<T, B>(&self, broadcast_type: BroadcastType<B>, data: T) -> Option<ReceiverCount>
822 where
823 T: Into<Vec<u8>>,
824 B: BroadcastTypeTrait,
825 {
826 self.try_send(broadcast_type, data).unwrap()
827 }
828
829 /// Runs the WebSocket connection, handling incoming requests and outgoing messages.
830 ///
831 /// This asynchronous function continuously monitors for new WebSocket requests
832 /// and incoming broadcast messages, processing them according to the configured hooks.
833 ///
834 /// # Type Parameters
835 ///
836 /// - `BroadcastTypeTrait`: The type implementing `BroadcastTypeTrait`.
837 ///
838 /// # Arguments
839 ///
840 /// - `WebSocketConfig<BroadcastTypeTrait>` - The WebSocket configuration containing the configuration for this WebSocket instance.
841 ///
842 /// # Panics
843 ///
844 /// Panics if the context in the WebSocket configuration is not set (i.e., it's the default context).
845 /// Panics if the broadcast type in the WebSocket configuration is `BroadcastType::Unknown`.
846 pub async fn run<B>(&self, websocket_config: WebSocketConfig<B>)
847 where
848 B: BroadcastTypeTrait,
849 {
850 let ctx: Context = websocket_config.get_context().clone();
851 if ctx.to_string() == Context::default().to_string() {
852 panic!("Context must be set");
853 }
854 let capacity: Capacity = websocket_config.get_capacity();
855 let broadcast_type: BroadcastType<B> = websocket_config.get_broadcast_type().clone();
856 let mut receiver: Receiver<Vec<u8>> = match &broadcast_type {
857 BroadcastType::PointToPoint(key1, key2) => self.point_to_point(key1, key2, capacity),
858 BroadcastType::PointToGroup(key) => self.point_to_group(key, capacity),
859 BroadcastType::Unknown => panic!("BroadcastType must be PointToPoint or PointToGroup"),
860 };
861 let key: String = BroadcastType::get_key(broadcast_type);
862 websocket_config.get_connected_hook()(&ctx).await;
863 let sended_hook: &ServerHookHandler = websocket_config.get_sended_hook();
864 let request_hook: &ServerHookHandler = websocket_config.get_request_hook();
865 let closed_hook: &ServerHookHandler = websocket_config.get_closed_hook();
866 let result_handle = || async {
867 ctx.aborted().await;
868 ctx.closed().await;
869 };
870 loop {
871 tokio::select! {
872 request_res = ctx.ws_from_stream() => {
873 let mut is_err: bool = false;
874 if request_res.is_ok() {
875 request_hook(&ctx).await;
876 } else {
877 is_err = true;
878 closed_hook(&ctx).await;
879 }
880 if ctx.get_aborted().await {
881 continue;
882 }
883 if ctx.get_closed().await {
884 break;
885 }
886 let body: ResponseBody = ctx.get_response_body().await;
887 is_err = self.broadcast_map.try_send(&key, body).is_err() || is_err;
888 sended_hook(&ctx).await;
889 if is_err || ctx.get_closed().await{
890 break;
891 }
892 },
893 msg_res = receiver.recv() => {
894 if let Ok(msg) = &msg_res {
895 if ctx.try_send_body_list_with_data(&WebSocketFrame::create_frame_list(msg)).await.is_ok() {
896 continue;
897 } else {
898 break;
899 }
900 }
901 break;
902 }
903 }
904 }
905 result_handle().await;
906 }
907}