feat: New extension trait for websocket online users
Signed-off-by: Awiteb <a@4rs.nl>
This commit is contained in:
parent
6f43e44745
commit
cd2a9ea03e
1 changed files with 67 additions and 2 deletions
|
@ -18,10 +18,16 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use oxidetalis_config::Config;
|
use oxidetalis_config::Config;
|
||||||
use salvo::Depot;
|
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
|
||||||
|
use salvo::{websocket::Message, Depot};
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::{routes::DEPOT_NONCE_CACHE_SIZE, NonceCache};
|
use crate::{
|
||||||
|
routes::DEPOT_NONCE_CACHE_SIZE,
|
||||||
|
websocket::{OnlineUsers, ServerEvent, SocketUserData},
|
||||||
|
NonceCache,
|
||||||
|
};
|
||||||
|
|
||||||
/// Extension trait for the Depot.
|
/// Extension trait for the Depot.
|
||||||
pub trait DepotExt {
|
pub trait DepotExt {
|
||||||
|
@ -42,6 +48,24 @@ pub trait NonceCacheExt {
|
||||||
fn add_nonce(&self, nonce: &[u8; 16], limit: &usize) -> bool;
|
fn add_nonce(&self, nonce: &[u8; 16], limit: &usize) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension trait for online websocket users
|
||||||
|
pub trait OnlineUsersExt {
|
||||||
|
/// Add new user to the online users
|
||||||
|
async fn add_user(&self, conn_id: &Uuid, data: SocketUserData);
|
||||||
|
|
||||||
|
/// Remove user from online users
|
||||||
|
async fn remove_user(&self, conn_id: &Uuid);
|
||||||
|
|
||||||
|
/// Ping all online users
|
||||||
|
async fn ping_all(&self);
|
||||||
|
|
||||||
|
/// Update user pong at time
|
||||||
|
async fn update_pong(&self, conn_id: &Uuid);
|
||||||
|
|
||||||
|
/// Disconnect inactive users (who not respond for the ping event)
|
||||||
|
async fn disconnect_inactive_users(&self);
|
||||||
|
}
|
||||||
|
|
||||||
impl DepotExt for Depot {
|
impl DepotExt for Depot {
|
||||||
fn db_conn(&self) -> &DatabaseConnection {
|
fn db_conn(&self) -> &DatabaseConnection {
|
||||||
self.obtain::<Arc<DatabaseConnection>>()
|
self.obtain::<Arc<DatabaseConnection>>()
|
||||||
|
@ -91,3 +115,44 @@ impl NonceCacheExt for &NonceCache {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl OnlineUsersExt for OnlineUsers {
|
||||||
|
async fn add_user(&self, conn_id: &Uuid, data: SocketUserData) {
|
||||||
|
self.write().await.insert(*conn_id, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn remove_user(&self, conn_id: &Uuid) {
|
||||||
|
self.write().await.remove(conn_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn ping_all(&self) {
|
||||||
|
let now = Utc::now();
|
||||||
|
self.write().await.par_iter_mut().for_each(|(_, u)| {
|
||||||
|
u.pinged_at = now;
|
||||||
|
let _ = u.sender.unbounded_send(Ok(Message::from(
|
||||||
|
&ServerEvent::ping().sign(&u.shared_secret),
|
||||||
|
)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_pong(&self, conn_id: &Uuid) {
|
||||||
|
if let Some(user) = self.write().await.get_mut(conn_id) {
|
||||||
|
user.ponged_at = Utc::now()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn disconnect_inactive_users(&self) {
|
||||||
|
let now = Utc::now().timestamp();
|
||||||
|
let is_inactive =
|
||||||
|
|u: &SocketUserData| u.pinged_at > u.ponged_at && now - u.pinged_at.timestamp() >= 5;
|
||||||
|
self.read()
|
||||||
|
.await
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, u)| is_inactive(u))
|
||||||
|
.for_each(|(_, u)| {
|
||||||
|
log::info!("Disconnected from {}, inactive", u.public_key);
|
||||||
|
u.sender.close_channel()
|
||||||
|
});
|
||||||
|
self.write().await.retain(|_, u| !is_inactive(u));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue