// This is the first point when WebRTC ask for a connection use super::client::RTCClient; use crate::core::AppState; use crate::models::{channel, user}; use axum::extract::ws::{Message, WebSocket}; use futures_util::{SinkExt, StreamExt}; use tokio::sync::mpsc; // 1. Le frontend ouvre /rtc/{channel_id} // 2. Axum extrait channel_id // 3. CurrentUser identifie l'utilisateur // 4. Le serveur vérifie le canal et les permissions // 5. Le serveur accepte le WebSocket // 6. Le client envoie son SDP Offer // 7. Le serveur crée la PeerConnection // 8. Le serveur applique l'Offer // 9. Le serveur crée une SDP Answer // 10. Le serveur renvoie l'Answer // 11. Les candidats ICE sont échangés // 12. À la déconnexion, la PeerConnection est fermée pub async fn ws_entrypoint_handler( socket: WebSocket, state: AppState, channel: channel::Model, user: user::Model, ) { let (mut sender, mut receiver) = socket.split(); let (tx, mut rx) = mpsc::unbounded_channel::(); let peer_connection = state.rtc.new_peer_connection(); let mut rtc_client = RTCClient::new(user, channel, peer_connection, tx); // Task pour envoyer les message au frontend depuis RTCClient let mut send_task = tokio::spawn(async move { while let Some(message) = rx.recv().await { if sender.send(message).await.is_err() { break; } } }); // Task pour recevoir les messages du frontend afin de les transmettre à RTCClient let client_clone = rtc_client.clone(); let mut recv_task = tokio::spawn(async move { while let Some(Ok(message)) = receiver.next().await { client_clone.on_message(message).await; } }); tokio::select! { _ = (&mut send_task) => recv_task.abort(), _ = (&mut recv_task) => send_task.abort(), }; }