#[cfg(not(target_arch = "wasm32"))]
use crate::client::HybridClient;
#[cfg(target_arch = "wasm32")]
use crate::client::WebSocketClient;
use crate::client::builder::{BaseClientBuilderConfig, ClientWrapper};
use crate::common::error::Result;
use crate::common::protocol::Frame;
use crate::transport::events::{ConnectionEvent, ConnectionObserver};
use std::sync::Arc;
pub type ClientMessageHandler = Box<dyn Fn(&Frame) -> Result<()> + Send + Sync>;
pub type ClientEventHandler = Box<dyn Fn(&ConnectionEvent) + Send + Sync>;
struct SimpleClientObserver {
message_handler: Option<ClientMessageHandler>,
event_handler: Option<ClientEventHandler>,
}
impl ConnectionObserver for SimpleClientObserver {
fn on_event(&self, event: &ConnectionEvent) {
if let Some(ref handler) = self.event_handler {
handler(event);
}
if let ConnectionEvent::Message(data) = event
&& let Some(ref handler) = self.message_handler
&& let Ok(frame) = crate::common::MessageParser::new(
crate::common::protocol::SerializationFormat::Protobuf,
crate::common::compression::CompressionAlgorithm::None,
crate::common::encryption::EncryptionAlgorithm::None,
)
.parse(data)
&& let Err(e) = handler(&frame)
{
tracing::error!("消息处理错误: {:?}", e);
}
}
}
pub struct SimpleClient {
wrapper: ClientWrapper,
observer: Arc<SimpleClientObserver>,
}
impl SimpleClient {
pub async fn connect(&mut self) -> Result<()> {
self.wrapper
.add_observer(self.observer.clone() as Arc<dyn ConnectionObserver>)
.await;
self.wrapper.connect().await
}
pub async fn disconnect(&mut self) -> Result<()> {
self.wrapper.disconnect().await
}
pub async fn send_frame(&mut self, frame: &Frame) -> Result<()> {
self.wrapper.send_frame(frame).await
}
pub async fn send_frame_and_wait(
&mut self,
frame: &Frame,
timeout: std::time::Duration,
) -> Result<Frame> {
self.wrapper.send_frame_and_wait(frame, timeout).await
}
pub async fn is_connected(&self) -> bool {
self.wrapper.is_connected_async().await
}
pub async fn connection_id(&self) -> Option<String> {
self.wrapper.connection_id_async().await
}
pub fn active_protocol(&self) -> crate::common::config_types::TransportProtocol {
self.wrapper.active_protocol()
}
pub async fn parser_snapshot(&self) -> crate::common::MessageParser {
self.wrapper.parser_snapshot().await
}
pub async fn wait_for_negotiation(&self, timeout: std::time::Duration) -> Result<()> {
self.wrapper.wait_for_negotiation(timeout).await
}
}
pub struct ClientBuilder {
base: BaseClientBuilderConfig,
message_handler: Option<ClientMessageHandler>,
event_handler: Option<ClientEventHandler>,
}
impl ClientBuilder {
pub fn new(server_url: impl Into<String>) -> Self {
Self {
base: BaseClientBuilderConfig::new(server_url),
message_handler: None,
event_handler: None,
}
}
pub fn on_message<F>(mut self, handler: F) -> Self
where
F: Fn(&Frame) -> Result<()> + Send + Sync + 'static,
{
self.message_handler = Some(Box::new(handler));
self
}
pub fn on_event<F>(mut self, handler: F) -> Self
where
F: Fn(&ConnectionEvent) + Send + Sync + 'static,
{
self.event_handler = Some(Box::new(handler));
self
}
pub fn with_protocol(
mut self,
protocol: crate::common::config_types::TransportProtocol,
) -> Self {
self.base = self.base.with_protocol(protocol);
self
}
pub fn with_protocol_race(
mut self,
protocols: Vec<crate::common::config_types::TransportProtocol>,
) -> Self {
self.base = self.base.with_protocol_race(protocols);
self
}
pub fn with_protocol_url(
mut self,
protocol: crate::common::config_types::TransportProtocol,
url: String,
) -> Self {
self.base = self.base.with_protocol_url(protocol, url);
self
}
pub fn with_user_id(mut self, user_id: String) -> Self {
self.base = self.base.with_user_id(user_id);
self
}
pub fn with_device_info(mut self, device_info: crate::common::device::DeviceInfo) -> Self {
self.base = self.base.with_device_info(device_info);
self
}
pub fn with_token(mut self, token: String) -> Self {
self.base = self.base.with_token(token);
self
}
pub fn with_format(mut self, format: crate::common::protocol::SerializationFormat) -> Self {
self.base = self.base.with_format(format);
self
}
pub fn with_compression(
mut self,
compression: crate::common::compression::CompressionAlgorithm,
) -> Self {
self.base = self.base.with_compression(compression);
self
}
pub fn with_heartbeat(
mut self,
heartbeat: crate::common::config_types::HeartbeatConfig,
) -> Self {
self.base = self.base.with_heartbeat(heartbeat);
self
}
pub fn with_tls(mut self, tls: crate::common::config_types::TlsConfig) -> Self {
self.base = self.base.with_tls(tls);
self
}
pub fn with_connect_timeout(mut self, timeout: std::time::Duration) -> Self {
self.base = self.base.with_connect_timeout(timeout);
self
}
pub fn with_reconnect_interval(mut self, interval: std::time::Duration) -> Self {
self.base = self.base.with_reconnect_interval(interval);
self
}
pub fn with_max_reconnect_attempts(mut self, max: Option<u32>) -> Self {
self.base = self.base.with_max_reconnect_attempts(max);
self
}
pub fn enable_router(mut self) -> Self {
self.base = self.base.enable_router();
self
}
pub fn build(self) -> Result<SimpleClient> {
let observer = Arc::new(SimpleClientObserver {
message_handler: self.message_handler,
event_handler: self.event_handler,
});
let client = {
#[cfg(not(target_arch = "wasm32"))]
{
HybridClient::new(self.base.config)?
}
#[cfg(target_arch = "wasm32")]
{
WebSocketClient::new(self.base.config)
}
};
let wrapper = ClientWrapper::new(client);
Ok(SimpleClient { wrapper, observer })
}
}