use crate::common::error::Result;
use crate::common::protocol::{Frame, PayloadCommand};
use crate::server::HybridServer;
use crate::server::builder::{BaseServerBuilderConfig, ServerWrapper};
use crate::server::events::handler::ServerEventHandler;
use crate::server::handle::ServerHandle;
use async_trait::async_trait;
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct MessageContext {
pub connection_id: String,
handle: Arc<dyn ServerHandle>,
}
impl MessageContext {
fn new(connection_id: String, handle: Arc<dyn ServerHandle>) -> Self {
Self {
connection_id,
handle,
}
}
pub async fn send_to(&self, connection_id: &str, frame: &Frame) -> Result<()> {
self.handle.send_to(connection_id, frame).await
}
pub async fn send_to_user(&self, user_id: &str, frame: &Frame) -> Result<()> {
self.handle.send_to_user(user_id, frame).await
}
pub async fn broadcast(&self, frame: &Frame) -> Result<()> {
self.handle.broadcast(frame).await
}
pub async fn broadcast_except(&self, frame: &Frame, exclude_connection_id: &str) -> Result<()> {
self.handle
.broadcast_except(frame, exclude_connection_id)
.await
}
pub async fn disconnect(&self, connection_id: &str) -> Result<()> {
self.handle.disconnect(connection_id).await
}
pub fn connection_count(&self) -> usize {
self.handle.connection_count()
}
pub fn user_count(&self) -> usize {
self.handle.user_count()
}
}
pub type MessageHandlerFn = Box<
dyn for<'a> Fn(
&'a Frame,
&'a MessageContext,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Option<Frame>>> + Send + 'a>,
> + Send
+ Sync,
>;
pub type OnConnectFn = Box<
dyn for<'a> Fn(
&'a str,
&'a MessageContext,
)
-> std::pin::Pin<Box<dyn std::future::Future<Output = Result<()>> + Send + 'a>>
+ Send
+ Sync,
>;
pub type OnDisconnectFn = Box<
dyn for<'a> Fn(
&'a str,
&'a MessageContext,
)
-> std::pin::Pin<Box<dyn std::future::Future<Output = Result<()>> + Send + 'a>>
+ Send
+ Sync,
>;
struct SimpleConnectionHandler {
message_handler: Option<MessageHandlerFn>,
on_connect: Option<OnConnectFn>,
on_disconnect: Option<OnDisconnectFn>,
handle: Arc<Mutex<Option<Arc<dyn ServerHandle>>>>,
}
impl SimpleConnectionHandler {
async fn set_handle(&self, handle: Arc<dyn ServerHandle>) {
*self.handle.lock().await = Some(handle);
}
}
struct SimpleEventHandlerAdapter {
handler: Arc<SimpleConnectionHandler>,
}
#[async_trait]
impl ServerEventHandler for SimpleEventHandlerAdapter {
async fn handle_message(
&self,
command: &PayloadCommand,
connection_id: &str,
) -> Result<Option<Frame>> {
let handle = {
let handle_guard = self.handler.handle.lock().await;
handle_guard.clone()
};
let context = if let Some(ref handle) = handle {
MessageContext::new(connection_id.to_string(), Arc::clone(handle))
} else {
return Err(crate::common::error::FlareError::general_error(
"Server handle is not available",
));
};
let frame = Frame {
message_id: command.message_id.clone(),
command: Some(crate::common::protocol::flare::core::commands::Command {
r#type: Some(
crate::common::protocol::flare::core::commands::command::Type::Payload(
command.clone(),
),
),
}),
metadata: std::collections::HashMap::new(),
reliability: crate::common::protocol::Reliability::AtLeastOnce as i32,
timestamp: 0,
};
if let Some(ref message_handler) = self.handler.message_handler {
message_handler(&frame, &context).await
} else {
Ok(None)
}
}
async fn on_connect(&self, connection_id: &str) -> Result<()> {
let handle = {
let handle_guard = self.handler.handle.lock().await;
handle_guard.clone()
};
let context = if let Some(ref handle) = handle {
MessageContext::new(connection_id.to_string(), Arc::clone(handle))
} else {
return Err(crate::common::error::FlareError::general_error(
"Server handle is not available",
));
};
if let Some(ref on_connect) = self.handler.on_connect {
on_connect(connection_id, &context).await
} else {
Ok(())
}
}
async fn on_disconnect(&self, connection_id: &str, _reason: Option<&str>) -> Result<()> {
let handle = {
let handle_guard = self.handler.handle.lock().await;
handle_guard.clone()
};
let context = if let Some(ref handle) = handle {
MessageContext::new(connection_id.to_string(), Arc::clone(handle))
} else {
return Err(crate::common::error::FlareError::general_error(
"Server handle is not available",
));
};
if let Some(ref on_disconnect) = self.handler.on_disconnect {
on_disconnect(connection_id, &context).await
} else {
Ok(())
}
}
}
pub struct SimpleServer {
wrapper: ServerWrapper,
handler: Arc<SimpleConnectionHandler>,
handle: Arc<dyn ServerHandle>,
}
impl SimpleServer {
pub async fn start(&mut self) -> Result<()> {
self.handler.set_handle(Arc::clone(&self.handle)).await;
self.wrapper.start().await
}
pub async fn stop(&mut self) -> Result<()> {
self.wrapper.stop().await
}
pub fn is_running(&self) -> bool {
self.wrapper.is_running()
}
pub fn connection_count(&self) -> usize {
self.wrapper.connection_count()
}
pub fn user_count(&self) -> usize {
self.wrapper.user_count()
}
pub fn handle(&self) -> Arc<dyn ServerHandle> {
Arc::clone(&self.handle)
}
pub async fn send_to(&self, connection_id: &str, frame: &Frame) -> Result<()> {
self.wrapper.send_to(connection_id, frame).await
}
pub async fn send_to_user(&self, user_id: &str, frame: &Frame) -> Result<()> {
self.wrapper.send_to_user(user_id, frame).await
}
pub async fn broadcast(&self, frame: &Frame) -> Result<()> {
self.wrapper.broadcast(frame).await
}
pub async fn broadcast_except(&self, frame: &Frame, exclude_connection_id: &str) -> Result<()> {
self.wrapper
.broadcast_except(frame, exclude_connection_id)
.await
}
pub async fn disconnect(&self, connection_id: &str) -> Result<()> {
self.wrapper.disconnect(connection_id).await
}
pub fn protocols(&self) -> Vec<crate::common::config_types::TransportProtocol> {
self.wrapper.protocols()
}
}
pub struct ServerBuilder {
base: BaseServerBuilderConfig,
message_handler: Option<MessageHandlerFn>,
on_connect: Option<OnConnectFn>,
on_disconnect: Option<OnDisconnectFn>,
}
impl ServerBuilder {
pub fn new(bind_address: impl Into<String>) -> Self {
Self {
base: BaseServerBuilderConfig::new(bind_address),
message_handler: None,
on_connect: None,
on_disconnect: None,
}
}
pub fn with_authenticator(
mut self,
authenticator: Arc<dyn crate::server::auth::Authenticator>,
) -> Self {
self.base = self.base.with_authenticator(authenticator);
self
}
pub fn enable_auth(mut self) -> Self {
self.base = self.base.enable_auth();
self
}
pub fn with_auth_timeout(mut self, timeout: std::time::Duration) -> Self {
self.base = self.base.with_auth_timeout(timeout);
self
}
pub fn on_message<F>(mut self, handler: F) -> Self
where
F: for<'a> Fn(
&'a Frame,
&'a MessageContext,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<Option<Frame>>> + Send + 'a>,
> + Send
+ Sync
+ 'static,
{
self.message_handler = Some(Box::new(move |frame, ctx| handler(frame, ctx)));
self
}
pub fn on_connect<F>(mut self, handler: F) -> Self
where
F: for<'a> Fn(
&'a str,
&'a MessageContext,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<()>> + Send + 'a>,
> + Send
+ Sync
+ 'static,
{
self.on_connect = Some(Box::new(move |conn_id, ctx| handler(conn_id, ctx)));
self
}
pub fn on_disconnect<F>(mut self, handler: F) -> Self
where
F: for<'a> Fn(
&'a str,
&'a MessageContext,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = Result<()>> + Send + 'a>,
> + Send
+ Sync
+ 'static,
{
self.on_disconnect = Some(Box::new(move |conn_id, ctx| handler(conn_id, ctx)));
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_protocols(
mut self,
protocols: Vec<crate::common::config_types::TransportProtocol>,
) -> Self {
self.base = self.base.with_protocols(protocols);
self
}
pub fn with_max_connections(mut self, max: usize) -> Self {
self.base = self.base.with_max_connections(max);
self
}
pub fn with_handshake_timeout(mut self, timeout: std::time::Duration) -> Self {
self.base = self.base.with_handshake_timeout(timeout);
self
}
pub fn with_max_handshake_concurrency(mut self, max: usize) -> Self {
self.base = self.base.with_max_handshake_concurrency(max);
self
}
pub fn with_write_timeout(mut self, timeout: std::time::Duration) -> Self {
self.base = self.base.with_write_timeout(timeout);
self
}
pub fn with_fanout_concurrency(mut self, max: usize) -> Self {
self.base = self.base.with_fanout_concurrency(max);
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_default_format(
mut self,
format: crate::common::protocol::SerializationFormat,
) -> Self {
self.base = self.base.with_default_format(format);
self
}
pub fn with_default_compression(
mut self,
compression: crate::common::compression::CompressionAlgorithm,
) -> Self {
self.base = self.base.with_default_compression(compression);
self
}
pub fn build(self) -> Result<SimpleServer> {
let handler = Arc::new(SimpleConnectionHandler {
message_handler: self.message_handler,
on_connect: self.on_connect,
on_disconnect: self.on_disconnect,
handle: Arc::new(Mutex::new(None)),
});
let event_handler: Arc<dyn crate::server::events::handler::ServerEventHandler> =
Arc::new(SimpleEventHandlerAdapter {
handler: handler.clone(),
});
let server = HybridServer::with_connection_manager(
self.base.config,
None,
None,
Some(event_handler),
self.base.authenticator,
)?;
let wrapper = ServerWrapper::new(server);
let handle = wrapper.get_server_handle().ok_or_else(|| {
crate::common::error::FlareError::general_error("Failed to create ServerHandle")
})?;
Ok(SimpleServer {
wrapper,
handler,
handle,
})
}
}