init
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use crate::core::AppState;
|
||||
use crate::http::context::CurrentUser;
|
||||
use crate::models::user::Model as User;
|
||||
use crate::permissions::ChannelPermission;
|
||||
use crate::routes::gateway::GatewayClient;
|
||||
use axum::{
|
||||
extract::{
|
||||
@@ -13,7 +12,6 @@ use axum::{
|
||||
use futures_util::{sink::SinkExt, stream::StreamExt};
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::mpsc;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct WsQuery {
|
||||
@@ -43,17 +41,9 @@ async fn handle_socket(socket: WebSocket, state: AppState, user: User) {
|
||||
let (mut sender, mut receiver) = socket.split();
|
||||
let (tx, mut rx) = mpsc::unbounded_channel::<Message>();
|
||||
|
||||
let channel_ids = match accessible_channel_ids(&state, &user).await {
|
||||
Ok(channel_ids) => channel_ids,
|
||||
Err(error) => {
|
||||
tracing::error!(user_id = %user.id, ?error, "Unable to resolve gateway channel access");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut client = GatewayClient::new(user, tx, state.event_bus.clone());
|
||||
client.on_connect().await;
|
||||
state.gateway.add_client(client.clone(), channel_ids);
|
||||
state.gateway.add_client(client.clone());
|
||||
|
||||
// Task pour envoyer les messages du canal mpsc vers le WebSocket
|
||||
let mut send_task = tokio::spawn(async move {
|
||||
@@ -82,43 +72,3 @@ async fn handle_socket(socket: WebSocket, state: AppState, user: User) {
|
||||
// // Déconnexion (Disconnect)
|
||||
client.on_disconnect().await;
|
||||
}
|
||||
|
||||
async fn accessible_channel_ids(state: &AppState, user: &User) -> Result<Vec<Uuid>, anyhow::Error> {
|
||||
if user.is_superuser {
|
||||
return Ok(state
|
||||
.repositories
|
||||
.channel
|
||||
.get_all()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|channel| channel.id)
|
||||
.collect());
|
||||
}
|
||||
|
||||
let mut channel_ids = Vec::new();
|
||||
for server in state.repositories.server.get_all().await? {
|
||||
if state
|
||||
.repositories
|
||||
.server
|
||||
.get_user(server.id, user.id)
|
||||
.await?
|
||||
.is_none()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let tree = state
|
||||
.repositories
|
||||
.server_tree
|
||||
.get_for_user(server.id, user.id)
|
||||
.await?;
|
||||
channel_ids.extend(tree.channels.into_iter().filter_map(|channel| {
|
||||
channel
|
||||
.permissions
|
||||
.filter(|permissions| permissions.contains(ChannelPermission::READ_CHANNEL))
|
||||
.map(|_| channel.channel.id)
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(channel_ids)
|
||||
}
|
||||
|
||||
+11
-27
@@ -10,21 +10,21 @@ use axum::extract::ws::Message;
|
||||
use event_bus::EventBus;
|
||||
use events::GatewayEvent;
|
||||
use parking_lot::RwLock;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::task::JoinHandle;
|
||||
use uuid::Uuid;
|
||||
use crate::services::Services;
|
||||
|
||||
pub mod events;
|
||||
pub mod handlers;
|
||||
pub mod routes;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
pub struct GatewayManager {
|
||||
// Chaque connexion est inscrite dans les groupes des canaux accessibles.
|
||||
pub clients: RwLock<HashMap<ConnectionKey, GatewayClient>>,
|
||||
channel_subscribers: RwLock<HashMap<Uuid, HashSet<ConnectionKey>>>,
|
||||
services: Arc<Services>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@@ -43,6 +43,9 @@ pub struct GatewayClient {
|
||||
}
|
||||
|
||||
impl GatewayManager {
|
||||
pub fn new(services: Arc<Services>) -> Self {
|
||||
Self { clients: RwLock::new(HashMap::new()), services }
|
||||
}
|
||||
/// Démarre les routeurs centraux des événements de messages.
|
||||
pub fn start(self: &Arc<Self>, event_bus: Arc<EventBus>) {
|
||||
let manager = Arc::clone(self);
|
||||
@@ -84,29 +87,15 @@ impl GatewayManager {
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn add_client(
|
||||
&self,
|
||||
gateway_client: GatewayClient,
|
||||
channel_ids: impl IntoIterator<Item = Uuid>,
|
||||
) {
|
||||
pub(crate) fn add_client(&self, gateway_client: GatewayClient) {
|
||||
let key = gateway_client.key();
|
||||
self.clients.write().insert(key, gateway_client);
|
||||
|
||||
let mut subscribers = self.channel_subscribers.write();
|
||||
for channel_id in channel_ids {
|
||||
subscribers.entry(channel_id).or_default().insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn remove_client(&self, gateway_client: &GatewayClient) {
|
||||
let key = gateway_client.key();
|
||||
self.clients.write().remove(&key);
|
||||
|
||||
let mut subscribers = self.channel_subscribers.write();
|
||||
for channel_subscribers in subscribers.values_mut() {
|
||||
channel_subscribers.remove(&key);
|
||||
}
|
||||
subscribers.retain(|_, values| !values.is_empty());
|
||||
}
|
||||
|
||||
fn broadcast_message<T: serde::Serialize>(
|
||||
@@ -124,15 +113,10 @@ impl GatewayManager {
|
||||
return;
|
||||
};
|
||||
|
||||
let keys = self
|
||||
.channel_subscribers
|
||||
.read()
|
||||
.get(&channel_id)
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
let users = self.services.realtime_registry.users_for_channel(channel_id);
|
||||
let clients = self.clients.read();
|
||||
for key in keys {
|
||||
if let Some(client) = clients.get(&key) {
|
||||
for (key, client) in clients.iter() {
|
||||
if users.contains(&key.user_id) {
|
||||
let _ = client.sender.send(Message::Text(json.clone().into()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user