pub struct Room { /* private fields */ }websockets and native only.Expand description
A WebSocket room that manages multiple client connections
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("chat_room".to_string());
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("user1".to_string(), tx));
room.join("user1".to_string(), client).await.unwrap();
assert_eq!(room.client_count().await, 1);Implementations§
Source§impl Room
impl Room
Sourcepub fn new(id: String) -> Room
pub fn new(id: String) -> Room
Create a new room with the given ID
§Examples
use reinhardt_websockets::room::Room;
let room = Room::new("general".to_string());
assert_eq!(room.id(), "general");Sourcepub fn id(&self) -> &str
pub fn id(&self) -> &str
Get the room ID
§Examples
use reinhardt_websockets::room::Room;
let room = Room::new("lobby".to_string());
assert_eq!(room.id(), "lobby");Sourcepub async fn join(
&self,
client_id: String,
client: Arc<WebSocketConnection>,
) -> Result<(), RoomError>
pub async fn join( &self, client_id: String, client: Arc<WebSocketConnection>, ) -> Result<(), RoomError>
Add a client to the room
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("chat".to_string());
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("alice".to_string(), tx));
room.join("alice".to_string(), client).await.unwrap();
assert!(room.has_client("alice").await);Sourcepub async fn leave(&self, client_id: &str) -> Result<(), RoomError>
pub async fn leave(&self, client_id: &str) -> Result<(), RoomError>
Remove a client from the room
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("chat".to_string());
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("bob".to_string(), tx));
room.join("bob".to_string(), client).await.unwrap();
assert!(room.has_client("bob").await);
room.leave("bob").await.unwrap();
assert!(!room.has_client("bob").await);Sourcepub async fn broadcast(&self, message: Message) -> BroadcastResult
pub async fn broadcast(&self, message: Message) -> BroadcastResult
Broadcast a message to all clients in the room.
Returns a BroadcastResult that reports which clients received the
message and which failed. Dead connections that fail during broadcast
are automatically removed from the room.
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::{WebSocketConnection, Message};
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("chat".to_string());
let (tx1, _rx1) = mpsc::unbounded_channel();
let (tx2, _rx2) = mpsc::unbounded_channel();
let client1 = Arc::new(WebSocketConnection::new("user1".to_string(), tx1));
let client2 = Arc::new(WebSocketConnection::new("user2".to_string(), tx2));
room.join("user1".to_string(), client1).await.unwrap();
room.join("user2".to_string(), client2).await.unwrap();
let msg = Message::text("Hello everyone!".to_string());
let result = room.broadcast(msg).await;
assert!(result.is_complete_success());
assert_eq!(result.successful.len(), 2);Sourcepub async fn broadcast_with_timeout(
&self,
message: Message,
send_timeout: Duration,
) -> BroadcastResult
pub async fn broadcast_with_timeout( &self, message: Message, send_timeout: Duration, ) -> BroadcastResult
Broadcasts a message to all clients with a per-client send timeout.
Slow consumers that do not accept the message within the given timeout are treated as failed and automatically removed from the room, applying backpressure to prevent slow receivers from blocking the entire broadcast.
§Arguments
message- The message to broadcastsend_timeout- Maximum time to wait for each client to accept the message
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::{WebSocketConnection, Message};
use tokio::sync::mpsc;
use std::sync::Arc;
use std::time::Duration;
let room = Room::new("chat".to_string());
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("user1".to_string(), tx));
room.join("user1".to_string(), client).await.unwrap();
let msg = Message::text("Hello!".to_string());
let result = room.broadcast_with_timeout(msg, Duration::from_secs(5)).await;
assert!(result.is_complete_success());Sourcepub async fn send_to(
&self,
client_id: &str,
message: Message,
) -> Result<(), RoomError>
pub async fn send_to( &self, client_id: &str, message: Message, ) -> Result<(), RoomError>
Send a message to a specific client
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::{WebSocketConnection, Message};
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("private".to_string());
let (tx, mut rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("charlie".to_string(), tx));
room.join("charlie".to_string(), client).await.unwrap();
let msg = Message::text("Private message".to_string());
room.send_to("charlie", msg).await.unwrap();
let received = rx.recv().await.unwrap();
match received {
Message::Text { data } => assert_eq!(data, "Private message"),
_ => panic!("Expected text message"),
}Sourcepub async fn client_count(&self) -> usize
pub async fn client_count(&self) -> usize
Get the number of clients in the room
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("game".to_string());
assert_eq!(room.client_count().await, 0);
let (tx1, _rx1) = mpsc::unbounded_channel();
let (tx2, _rx2) = mpsc::unbounded_channel();
let client1 = Arc::new(WebSocketConnection::new("player1".to_string(), tx1));
let client2 = Arc::new(WebSocketConnection::new("player2".to_string(), tx2));
room.join("player1".to_string(), client1).await.unwrap();
room.join("player2".to_string(), client2).await.unwrap();
assert_eq!(room.client_count().await, 2);Sourcepub async fn client_ids(&self) -> Vec<String>
pub async fn client_ids(&self) -> Vec<String>
Get all client IDs in the room
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("meeting".to_string());
let (tx1, _rx1) = mpsc::unbounded_channel();
let (tx2, _rx2) = mpsc::unbounded_channel();
let client1 = Arc::new(WebSocketConnection::new("dave".to_string(), tx1));
let client2 = Arc::new(WebSocketConnection::new("eve".to_string(), tx2));
room.join("dave".to_string(), client1).await.unwrap();
room.join("eve".to_string(), client2).await.unwrap();
let ids = room.client_ids().await;
assert_eq!(ids.len(), 2);
assert!(ids.contains(&"dave".to_string()));
assert!(ids.contains(&"eve".to_string()));Sourcepub async fn has_client(&self, client_id: &str) -> bool
pub async fn has_client(&self, client_id: &str) -> bool
Check if a client is in the room
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("support".to_string());
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("frank".to_string(), tx));
room.join("frank".to_string(), client).await.unwrap();
assert!(room.has_client("frank").await);
assert!(!room.has_client("grace").await);Sourcepub async fn set_metadata<T>(
&self,
key: &str,
value: T,
) -> Result<(), RoomError>where
T: Serialize,
pub async fn set_metadata<T>(
&self,
key: &str,
value: T,
) -> Result<(), RoomError>where
T: Serialize,
Set metadata for the room
§Examples
use reinhardt_websockets::room::Room;
use serde_json::json;
let room = Room::new("config".to_string());
room.set_metadata("max_users", json!(10)).await.unwrap();
room.set_metadata("topic", json!("General Discussion")).await.unwrap();
let max_users: i64 = room.get_metadata("max_users").await.unwrap().unwrap();
assert_eq!(max_users, 10);Sourcepub async fn get_metadata<T>(&self, key: &str) -> Result<Option<T>, RoomError>where
T: DeserializeOwned,
pub async fn get_metadata<T>(&self, key: &str) -> Result<Option<T>, RoomError>where
T: DeserializeOwned,
Get metadata from the room
§Examples
use reinhardt_websockets::room::Room;
use serde_json::json;
let room = Room::new("data".to_string());
room.set_metadata("counter", json!(42)).await.unwrap();
let counter: i64 = room.get_metadata("counter").await.unwrap().unwrap();
assert_eq!(counter, 42);
let missing: Option<String> = room.get_metadata("nonexistent").await.unwrap();
assert!(missing.is_none());Sourcepub async fn remove_metadata(&self, key: &str) -> Option<Value>
pub async fn remove_metadata(&self, key: &str) -> Option<Value>
Remove metadata from the room
§Examples
use reinhardt_websockets::room::Room;
use serde_json::json;
let room = Room::new("temp".to_string());
room.set_metadata("temp_key", json!("temp_value")).await.unwrap();
assert!(room.get_metadata::<String>("temp_key").await.unwrap().is_some());
room.remove_metadata("temp_key").await;
assert!(room.get_metadata::<String>("temp_key").await.unwrap().is_none());Sourcepub async fn clear_metadata(&self)
pub async fn clear_metadata(&self)
Clear all metadata
§Examples
use reinhardt_websockets::room::Room;
use serde_json::json;
let room = Room::new("reset".to_string());
room.set_metadata("key1", json!("value1")).await.unwrap();
room.set_metadata("key2", json!("value2")).await.unwrap();
room.clear_metadata().await;
assert!(room.get_metadata::<String>("key1").await.unwrap().is_none());
assert!(room.get_metadata::<String>("key2").await.unwrap().is_none());Sourcepub async fn is_empty(&self) -> bool
pub async fn is_empty(&self) -> bool
Check if room is empty
§Examples
use reinhardt_websockets::room::Room;
use reinhardt_websockets::WebSocketConnection;
use tokio::sync::mpsc;
use std::sync::Arc;
let room = Room::new("empty_check".to_string());
assert!(room.is_empty().await);
let (tx, _rx) = mpsc::unbounded_channel();
let client = Arc::new(WebSocketConnection::new("henry".to_string(), tx));
room.join("henry".to_string(), client).await.unwrap();
assert!(!room.is_empty().await);Auto Trait Implementations§
impl Freeze for Room
impl !RefUnwindSafe for Room
impl Send for Room
impl Sync for Room
impl Unpin for Room
impl UnsafeUnpin for Room
impl !UnwindSafe for Room
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T> IntoResult<T> for T
impl<T> IntoResult<T> for T
type Err = Infallible
fn into_result(self) -> Result<T, <T as IntoResult<T>>::Err>
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.