Message broadcast

This commit is contained in:
2026-08-20 16:39:56 +02:00
parent 0bce209dd1
commit 943dc96703
2 changed files with 49 additions and 14 deletions
+6
View File
@@ -45,6 +45,12 @@ pub async fn send_message(
server.message_store.insert_message(&channel_id, &stored)?; server.message_store.insert_message(&channel_id, &stored)?;
server
.broadcast(&ClientMethod::Messages {
messages: HashMap::from([(channel_id, vec![stored])]),
})
.await?;
Ok(()) Ok(())
} }
+43 -14
View File
@@ -9,7 +9,7 @@ use axum::{
response::Response, response::Response,
}; };
use ed25519_dalek::{SigningKey, VerifyingKey}; use ed25519_dalek::{SigningKey, VerifyingKey};
use tokio::sync::Mutex; use tokio::{sync::Mutex, task::JoinSet};
use crate::{ use crate::{
data::{config::Config, messages::MessageStore}, data::{config::Config, messages::MessageStore},
@@ -21,13 +21,13 @@ pub struct UserConnections {
pub meta: ClientMeta, pub meta: ClientMeta,
pub counter: AtomicU16, pub counter: AtomicU16,
pub public_key: VerifyingKey, pub public_key: VerifyingKey,
pub connections: HashMap<u16, Arc<Mutex<WebSocket>>>, pub connections: Mutex<HashMap<u16, Arc<Mutex<WebSocket>>>>,
} }
pub struct Server { pub struct Server {
pub key: SigningKey, pub key: SigningKey,
pub config: Config, pub config: Config,
pub clients: Mutex<HashMap<VerifyingKey, UserConnections>>, pub clients: Mutex<HashMap<VerifyingKey, Arc<UserConnections>>>,
pub message_store: MessageStore, pub message_store: MessageStore,
} }
@@ -53,21 +53,27 @@ impl Server {
let mut clients_meta = s.clients.lock().await; let mut clients_meta = s.clients.lock().await;
let clients = let clients = clients_meta
clients_meta .entry(public_key)
.entry(public_key) .or_insert_with(|| {
.or_insert_with(|| UserConnections { Arc::new(UserConnections {
meta, meta,
public_key: public_key, public_key: public_key,
counter: AtomicU16::new(0), counter: AtomicU16::new(0),
connections: HashMap::new(), connections: Mutex::new(HashMap::new()),
}); })
})
.clone();
let conid = clients let conid = clients
.counter .counter
.fetch_add(1, std::sync::atomic::Ordering::Relaxed); .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
clients.connections.insert(conid, client.clone()); clients
.connections
.lock()
.await
.insert(conid, client.clone());
if let Err(e) = read_loop(&s, public_key, &client).await { if let Err(e) = read_loop(&s, public_key, &client).await {
eprintln!("Failed to handle client: {e}"); eprintln!("Failed to handle client: {e}");
@@ -75,9 +81,11 @@ impl Server {
println!("Client connection closed") println!("Client connection closed")
} }
clients.connections.remove(&conid); let mut connections = clients.connections.lock().await;
if clients.connections.len() == 0 { connections.remove(&conid);
if connections.len() == 0 {
clients_meta.remove(&public_key); clients_meta.remove(&public_key);
} }
} }
@@ -88,11 +96,32 @@ impl Server {
} }
}) })
} }
pub async fn broadcast(self: &Arc<Self>, message: &ClientMethod) -> anyhow::Result<()> {
let mut set = JoinSet::new();
for (_, client) in self.clients.lock().await.iter() {
let msg = message.clone();
let client = client.clone();
set.spawn(async move { client.send(&msg).await });
}
// Await all spawned tasks to finish
while let Some(res) = set.join_next().await {
// handle task panic or errors if necessary
if let Ok(Err(e)) = res {
eprintln!("Failed to send to a client: {:?}", e);
}
}
Ok(())
}
} }
impl UserConnections { impl UserConnections {
pub async fn send(&self, message: &ClientMethod) -> anyhow::Result<()> { pub async fn send(&self, message: &ClientMethod) -> anyhow::Result<()> {
for (_, conn) in &self.connections { for (_, conn) in self.connections.lock().await.iter() {
send_socket(&mut *conn.lock().await, message).await?; send_socket(&mut *conn.lock().await, message).await?;
} }
@@ -100,7 +129,7 @@ impl UserConnections {
} }
pub async fn send_to(&self, id: u16, message: &ClientMethod) -> anyhow::Result<bool> { pub async fn send_to(&self, id: u16, message: &ClientMethod) -> anyhow::Result<bool> {
if let Some(conn) = self.connections.get(&id) { if let Some(conn) = self.connections.lock().await.get(&id) {
send_socket(&mut *conn.lock().await, message).await?; send_socket(&mut *conn.lock().await, message).await?;
Ok(true) Ok(true)