Skip to main content

ClientBuilder

Struct ClientBuilder 

Source
pub struct ClientBuilder<S: AppState> { /* private fields */ }

Implementations§

Source§

impl<S: AppState> ClientBuilder<S>

Source

pub fn new(connector: impl Connector<S> + 'static, state: S) -> Self

Creates a new builder with the essential components.

Examples found in repository?
examples/echo_client.rs (line 298)
294    pub async fn new(url: String) -> CoreResult<Self> {
295        // Use a simple connector (implement your own if needed)
296        let connector = DummyConnector::new(url);
297
298        let mut builder = ClientBuilder::new(connector, ());
299        builder =
300            builder.with_lightweight_handler(|msg, state, _| Box::pin(print_handler(msg, state)));
301        let (client, mut runner) = builder
302            .with_module::<EchoModule>()
303            .with_module::<StreamModule>()
304            .with_module::<PeriodicSenderModule>()
305            .build()
306            .await?;
307
308        // let echo_handle = client.get_handle::<EchoModule>().await.unwrap();
309        // let stream_handle = client.get_handle::<StreamModule>().await.unwrap();
310
311        // Start runner in background
312        let _runner = tokio::spawn(async move { runner.run().await });
313
314        Ok(Self { client, _runner })
315    }
More examples
Hide additional examples
examples/middleware_example.rs (line 227)
219async fn main() -> CoreResult<()> {
220    // Initialize tracing
221    tracing_subscriber::fmt::init();
222
223    // Create statistics middleware
224    let stats_middleware = Arc::new(StatisticsMiddleware::new());
225
226    // Build the client with middleware
227    let (client, _) = ClientBuilder::new(MockConnector, ExampleState)
228        .with_middleware(Box::new(LoggingMiddleware))
229        .with_middleware(Box::new(StatisticsMiddleware::new()))
230        .with_module::<ExampleModule>()
231        .build()
232        .await?;
233
234    info!("Client built with middleware layers");
235    tokio::time::sleep(Duration::from_secs(10)).await;
236    client.shutdown().await?;
237    // In a real application, you would:
238    // 1. Start the runner in a background task
239    // 2. Use the client to send messages
240    // 3. Check statistics periodically
241
242    // For demonstration, we'll just show the statistics
243    let stats = stats_middleware.get_stats();
244    info!("Current statistics: {:?}", stats);
245
246    Ok(())
247}
examples/testing_echo_client.rs (line 127)
124    pub async fn new(url: String) -> CoreResult<Self> {
125        let connector = DummyConnector::new(url);
126
127        let builder = ClientBuilder::new(connector, ()).with_module::<EchoModule>();
128
129        // // Create testing wrapper with custom configuration
130        // let testing_config = TestingConfig {
131        //     stats_interval: Duration::from_secs(10), // Log stats every 10 seconds
132        //     log_stats: true,
133        //     track_events: true,
134        //     max_reconnect_attempts: Some(3),
135        //     reconnect_delay: Duration::from_secs(5),
136        //     connection_timeout: Duration::from_secs(30),
137        //     auto_reconnect: true,
138        // };
139
140        let testing_wrapper = TestingWrapperBuilder::new()
141            .with_stats_interval(Duration::from_secs(10))
142            .with_log_stats(true)
143            .with_track_events(true)
144            .with_max_reconnect_attempts(Some(3))
145            .with_reconnect_delay(Duration::from_secs(5))
146            .with_connection_timeout(Duration::from_secs(30))
147            .with_auto_reconnect(true)
148            .build_with_middleware(builder)
149            .await?;
150
151        Ok(Self { testing_wrapper })
152    }
Source

pub fn on_connect( self, callback: impl Fn(Arc<S>, &AsyncSender<Message>) -> BoxFuture<'static, CoreResult<()>> + Send + Sync + 'static, ) -> Self

Sets the callback for the initial connection.

Source

pub fn on_reconnect( self, callback: Box<dyn ReconnectCallback<S> + Send + Sync + 'static>, ) -> Self

Sets the callback for subsequent reconnections.

Source

pub fn with_lightweight_handler( self, handler: impl Fn(Arc<Message>, Arc<S>, &AsyncSender<Message>) -> BoxFuture<'static, CoreResult<()>> + Send + Sync + 'static, ) -> Self

Adds a lightweight handler that receives all messages.

Examples found in repository?
examples/echo_client.rs (line 300)
294    pub async fn new(url: String) -> CoreResult<Self> {
295        // Use a simple connector (implement your own if needed)
296        let connector = DummyConnector::new(url);
297
298        let mut builder = ClientBuilder::new(connector, ());
299        builder =
300            builder.with_lightweight_handler(|msg, state, _| Box::pin(print_handler(msg, state)));
301        let (client, mut runner) = builder
302            .with_module::<EchoModule>()
303            .with_module::<StreamModule>()
304            .with_module::<PeriodicSenderModule>()
305            .build()
306            .await?;
307
308        // let echo_handle = client.get_handle::<EchoModule>().await.unwrap();
309        // let stream_handle = client.get_handle::<StreamModule>().await.unwrap();
310
311        // Start runner in background
312        let _runner = tokio::spawn(async move { runner.run().await });
313
314        Ok(Self { client, _runner })
315    }
Source

pub fn with_lightweight_module<M: LightweightModule<S>>(self) -> Self

Registers a lightweight module

Source

pub fn with_module<M: ApiModule<S>>(self) -> Self

Registers a full API module with the client.

Examples found in repository?
examples/echo_client.rs (line 302)
294    pub async fn new(url: String) -> CoreResult<Self> {
295        // Use a simple connector (implement your own if needed)
296        let connector = DummyConnector::new(url);
297
298        let mut builder = ClientBuilder::new(connector, ());
299        builder =
300            builder.with_lightweight_handler(|msg, state, _| Box::pin(print_handler(msg, state)));
301        let (client, mut runner) = builder
302            .with_module::<EchoModule>()
303            .with_module::<StreamModule>()
304            .with_module::<PeriodicSenderModule>()
305            .build()
306            .await?;
307
308        // let echo_handle = client.get_handle::<EchoModule>().await.unwrap();
309        // let stream_handle = client.get_handle::<StreamModule>().await.unwrap();
310
311        // Start runner in background
312        let _runner = tokio::spawn(async move { runner.run().await });
313
314        Ok(Self { client, _runner })
315    }
More examples
Hide additional examples
examples/middleware_example.rs (line 230)
219async fn main() -> CoreResult<()> {
220    // Initialize tracing
221    tracing_subscriber::fmt::init();
222
223    // Create statistics middleware
224    let stats_middleware = Arc::new(StatisticsMiddleware::new());
225
226    // Build the client with middleware
227    let (client, _) = ClientBuilder::new(MockConnector, ExampleState)
228        .with_middleware(Box::new(LoggingMiddleware))
229        .with_middleware(Box::new(StatisticsMiddleware::new()))
230        .with_module::<ExampleModule>()
231        .build()
232        .await?;
233
234    info!("Client built with middleware layers");
235    tokio::time::sleep(Duration::from_secs(10)).await;
236    client.shutdown().await?;
237    // In a real application, you would:
238    // 1. Start the runner in a background task
239    // 2. Use the client to send messages
240    // 3. Check statistics periodically
241
242    // For demonstration, we'll just show the statistics
243    let stats = stats_middleware.get_stats();
244    info!("Current statistics: {:?}", stats);
245
246    Ok(())
247}
examples/testing_echo_client.rs (line 127)
124    pub async fn new(url: String) -> CoreResult<Self> {
125        let connector = DummyConnector::new(url);
126
127        let builder = ClientBuilder::new(connector, ()).with_module::<EchoModule>();
128
129        // // Create testing wrapper with custom configuration
130        // let testing_config = TestingConfig {
131        //     stats_interval: Duration::from_secs(10), // Log stats every 10 seconds
132        //     log_stats: true,
133        //     track_events: true,
134        //     max_reconnect_attempts: Some(3),
135        //     reconnect_delay: Duration::from_secs(5),
136        //     connection_timeout: Duration::from_secs(30),
137        //     auto_reconnect: true,
138        // };
139
140        let testing_wrapper = TestingWrapperBuilder::new()
141            .with_stats_interval(Duration::from_secs(10))
142            .with_log_stats(true)
143            .with_track_events(true)
144            .with_max_reconnect_attempts(Some(3))
145            .with_reconnect_delay(Duration::from_secs(5))
146            .with_connection_timeout(Duration::from_secs(30))
147            .with_auto_reconnect(true)
148            .build_with_middleware(builder)
149            .await?;
150
151        Ok(Self { testing_wrapper })
152    }
Source

pub fn with_middleware( self, middleware: Box<dyn WebSocketMiddleware<S>>, ) -> Self

Adds a middleware layer to the client.

Middleware will be executed in the order they are added. They will be called for all WebSocket messages sent and received.

§Example
let builder = ClientBuilder::new(MyConnector, MyState)
    .with_middleware(Box::new(MyMiddleware));
Examples found in repository?
examples/middleware_example.rs (line 228)
219async fn main() -> CoreResult<()> {
220    // Initialize tracing
221    tracing_subscriber::fmt::init();
222
223    // Create statistics middleware
224    let stats_middleware = Arc::new(StatisticsMiddleware::new());
225
226    // Build the client with middleware
227    let (client, _) = ClientBuilder::new(MockConnector, ExampleState)
228        .with_middleware(Box::new(LoggingMiddleware))
229        .with_middleware(Box::new(StatisticsMiddleware::new()))
230        .with_module::<ExampleModule>()
231        .build()
232        .await?;
233
234    info!("Client built with middleware layers");
235    tokio::time::sleep(Duration::from_secs(10)).await;
236    client.shutdown().await?;
237    // In a real application, you would:
238    // 1. Start the runner in a background task
239    // 2. Use the client to send messages
240    // 3. Check statistics periodically
241
242    // For demonstration, we'll just show the statistics
243    let stats = stats_middleware.get_stats();
244    info!("Current statistics: {:?}", stats);
245
246    Ok(())
247}
Source

pub fn with_middleware_layers( self, middleware: Vec<Box<dyn WebSocketMiddleware<S>>>, ) -> Self

Adds multiple middleware layers at once.

This is a convenience method for adding multiple middleware layers.

§Example
let builder = ClientBuilder::new(MyConnector, MyState)
    .with_middleware_layers(vec![
        Box::new(MyMiddleware),
        Box::new(MyMiddleware),
    ]);
Source

pub fn with_middleware_stack(self, stack: MiddlewareStack<S>) -> Self

Applies a middleware stack to the client.

This replaces any existing middleware with the provided stack.

§Example
let mut stack = MiddlewareStack::new();
stack.add_layer(Box::new(MyMiddleware));

let builder = ClientBuilder::new(MyConnector, MyState)
    .with_middleware_stack(stack);
Source

pub fn with_max_allowed_loops(self, max_allowed_loops: u32) -> Self

Sets the maximum number of reconnection attempts. 0 means infinite attempts.

Source

pub fn with_reconnect_delay(self, reconnect_delay: Duration) -> Self

Sets the base delay for reconnection attempts.

Source

pub async fn build(self) -> CoreResult<(Client<S>, ClientRunner<S>)>

Assembles and returns the final Client handle and its ClientRunner.

Examples found in repository?
examples/echo_client.rs (line 305)
294    pub async fn new(url: String) -> CoreResult<Self> {
295        // Use a simple connector (implement your own if needed)
296        let connector = DummyConnector::new(url);
297
298        let mut builder = ClientBuilder::new(connector, ());
299        builder =
300            builder.with_lightweight_handler(|msg, state, _| Box::pin(print_handler(msg, state)));
301        let (client, mut runner) = builder
302            .with_module::<EchoModule>()
303            .with_module::<StreamModule>()
304            .with_module::<PeriodicSenderModule>()
305            .build()
306            .await?;
307
308        // let echo_handle = client.get_handle::<EchoModule>().await.unwrap();
309        // let stream_handle = client.get_handle::<StreamModule>().await.unwrap();
310
311        // Start runner in background
312        let _runner = tokio::spawn(async move { runner.run().await });
313
314        Ok(Self { client, _runner })
315    }
More examples
Hide additional examples
examples/middleware_example.rs (line 231)
219async fn main() -> CoreResult<()> {
220    // Initialize tracing
221    tracing_subscriber::fmt::init();
222
223    // Create statistics middleware
224    let stats_middleware = Arc::new(StatisticsMiddleware::new());
225
226    // Build the client with middleware
227    let (client, _) = ClientBuilder::new(MockConnector, ExampleState)
228        .with_middleware(Box::new(LoggingMiddleware))
229        .with_middleware(Box::new(StatisticsMiddleware::new()))
230        .with_module::<ExampleModule>()
231        .build()
232        .await?;
233
234    info!("Client built with middleware layers");
235    tokio::time::sleep(Duration::from_secs(10)).await;
236    client.shutdown().await?;
237    // In a real application, you would:
238    // 1. Start the runner in a background task
239    // 2. Use the client to send messages
240    // 3. Check statistics periodically
241
242    // For demonstration, we'll just show the statistics
243    let stats = stats_middleware.get_stats();
244    info!("Current statistics: {:?}", stats);
245
246    Ok(())
247}

Auto Trait Implementations§

§

impl<S> Freeze for ClientBuilder<S>

§

impl<S> !RefUnwindSafe for ClientBuilder<S>

§

impl<S> Send for ClientBuilder<S>

§

impl<S> Sync for ClientBuilder<S>

§

impl<S> Unpin for ClientBuilder<S>

§

impl<S> UnsafeUnpin for ClientBuilder<S>

§

impl<S> !UnwindSafe for ClientBuilder<S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more