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