diff --git a/socketio/src/asynchronous/client/builder.rs b/socketio/src/asynchronous/client/builder.rs index 44710e19..f9c2eae2 100644 --- a/socketio/src/asynchronous/client/builder.rs +++ b/socketio/src/asynchronous/client/builder.rs @@ -6,6 +6,7 @@ use rust_engineio::{ header::{HeaderMap, HeaderValue}, }; use std::collections::HashMap; +use std::sync::Arc; use url::Url; use crate::{error::Result, Event, Payload, TransportType}; @@ -38,6 +39,7 @@ pub struct ClientBuilder { pub(crate) max_reconnect_attempts: Option, pub(crate) reconnect_delay_min: u64, pub(crate) reconnect_delay_max: u64, + pub(crate) data: Option>, } impl ClientBuilder { @@ -97,9 +99,17 @@ impl ClientBuilder { max_reconnect_attempts: None, reconnect_delay_min: 1000, reconnect_delay_max: 5000, + data: None, } } + /// Sets the client's custom data. + // TODO: write example usage + pub fn set_data(mut self, data: Arc) -> Self { + self.data = Some(data); + self + } + /// Sets the target namespace of the client. The namespace should start /// with a leading `/`. Valid examples are e.g. `/admin`, `/foo`. /// If the String provided doesn't start with a leading `/`, it is diff --git a/socketio/src/asynchronous/client/client.rs b/socketio/src/asynchronous/client/client.rs index 67feb7db..9409940a 100644 --- a/socketio/src/asynchronous/client/client.rs +++ b/socketio/src/asynchronous/client/client.rs @@ -74,6 +74,7 @@ pub struct Client { auth: Option, builder: Arc>, disconnect_reason: Arc>, + data: Arc, } impl Client { @@ -87,11 +88,19 @@ impl Client { nsp: builder.namespace.to_owned(), outstanding_acks: Arc::new(RwLock::new(Vec::new())), auth: builder.auth.clone(), + data: builder.data.clone().unwrap_or(Arc::new(())), builder: Arc::new(RwLock::new(builder)), disconnect_reason: Arc::new(RwLock::new(DisconnectReason::default())), }) } + /// Attempts to fetch data given by [`ClientBuilder::set_data`] + /// + /// None is returned if data was not given or data does not match [`ClientBuilder::data`] + pub fn custom_data(&self) -> Option> { + Arc::clone(&self.data).downcast().ok() + } + /// Connects the client to a server. Afterwards the `emit_*` methods can be /// called to interact with the server. pub(crate) async fn connect(&self) -> Result<()> { diff --git a/socketio/src/client/builder.rs b/socketio/src/client/builder.rs index 724971f0..6caa46cb 100644 --- a/socketio/src/client/builder.rs +++ b/socketio/src/client/builder.rs @@ -41,6 +41,7 @@ pub struct ClientBuilder { opening_headers: Option, transport_type: TransportType, auth: Option, + data: Option>, pub(crate) reconnect: bool, pub(crate) reconnect_on_disconnect: bool, // None reconnect attempts represent infinity. @@ -98,9 +99,17 @@ impl ClientBuilder { max_reconnect_attempts: None, reconnect_delay_min: 1000, reconnect_delay_max: 5000, + data: None, } } + /// Sets the client's custom data. + // TODO: write example usage + pub fn set_data(mut self, data: Arc) -> Self { + self.data = Some(data); + self + } + /// Sets the target namespace of the client. The namespace should start /// with a leading `/`. Valid examples are e.g. `/admin`, `/foo`. pub fn namespace>(mut self, namespace: T) -> Self { @@ -365,6 +374,7 @@ impl ClientBuilder { self.on, self.on_any, self.auth, + self.data.unwrap_or(Arc::new(())), )?; socket.connect()?; diff --git a/socketio/src/client/raw_client.rs b/socketio/src/client/raw_client.rs index 0686683f..fd24d159 100644 --- a/socketio/src/client/raw_client.rs +++ b/socketio/src/client/raw_client.rs @@ -14,6 +14,7 @@ use std::time::Duration; use std::time::Instant; use crate::socket::Socket as InnerSocket; +use crate::client::builder::ClientBuilder; /// Represents an `Ack` as given back to the caller. Holds the internal `id` as /// well as the current ack'ed state. Holds data which will be accessible as @@ -41,6 +42,7 @@ pub struct RawClient { nsp: String, // Data send in the opening packet (commonly used as for auth) auth: Option, + data: Arc, } impl RawClient { @@ -54,6 +56,7 @@ impl RawClient { on: Arc>>>, on_any: Arc>>>, auth: Option, + data: Arc, ) -> Result { Ok(RawClient { socket, @@ -62,9 +65,17 @@ impl RawClient { on_any, outstanding_acks: Arc::new(Mutex::new(Vec::new())), auth, + data, }) } + /// Attempts to fetch data given by [`ClientBuilder::set_data`] + /// + /// None is returned if data was not given or data does not match [`ClientBuilder::data`] + pub fn custom_data(&self) -> Option> { + Arc::clone(&self.data).downcast().ok() + } + /// Connects the client to a server. Afterwards the `emit_*` methods can be /// called to interact with the server. Attention: it's not allowed to add a /// callback after a call to this method.