From 82971110604854040912b589fe0ece98ccec3984 Mon Sep 17 00:00:00 2001 From: Nell Date: Sat, 19 Sep 2026 21:34:06 +0200 Subject: [PATCH] init --- Cargo.lock | 24 ++++++++++++------------ Cargo.toml | 6 +++--- migration/Cargo.toml | 2 +- src/routes/rtc/handlers.rs | 15 ++++++++++++--- src/routes/rtc/routes.rs | 2 +- src/rtc/client.rs | 35 +++++++++++++++++++++++++++++++++++ src/rtc/mod.rs | 1 + src/rtc/ws_entrypoint.rs | 35 ++++++++++++++++++++++++++++++++--- 8 files changed, 97 insertions(+), 23 deletions(-) create mode 100644 src/rtc/client.rs diff --git a/Cargo.lock b/Cargo.lock index 5861631..6c04d51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2495,9 +2495,9 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "11.0.0" +version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881733cbc631fc9e472e24447ce32a64bedf2da498d6d8570b08edc87de71f65" +checksum = "e75fe14a82d81e5f5af639997db37d8b96045938a7ac6ab18cdbe1c7467e05e1" dependencies = [ "aws-lc-rs", "base64 0.22.1", @@ -3714,9 +3714,9 @@ dependencies = [ [[package]] name = "rustrtc" -version = "0.3.133" +version = "0.3.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d8307edee45813b075a3a7dd237ab68f41d7220c53cf2752802431f68c055db" +checksum = "282d086d81cf8908a2c3d6ecf068180b711a20f0412658da13f052608f00d936" dependencies = [ "aes 0.9.3", "aes-gcm", @@ -3787,9 +3787,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a334e83ced3ae3ee44db0f84d1fcf8d2087a1ad9bb9036f00f9f6067156ea197" +checksum = "e01d46a6e22b8ce84aba64fe97011669859bc7f7120a47f5b58839dcaaa4545c" dependencies = [ "async-stream", "async-trait", @@ -3835,9 +3835,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a53505884d7c907bcf4f7b4ddb1b29425e62fef8b98aea9c99e17781cceb798" +checksum = "2479056c3f9c96c8ec5b9091103050b5f3a0532c615d8ab01d3edb81af5c65a8" dependencies = [ "chrono", "clap", @@ -3852,9 +3852,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4039a86f9acc4d3b52747508b347dddc6fd725bbc429902ebeb6d26225fc2528" +checksum = "e24c82fc1e76c014dffe5ecdac8f654da73161d703a16ea13414581e07459c83" dependencies = [ "heck 0.5.0", "itertools 0.14.0", @@ -3868,9 +3868,9 @@ dependencies = [ [[package]] name = "sea-orm-migration" -version = "2.0.2" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd09adbef87100d07131a60a8c5508b53d0cf2136521f654aae47af5e6a097fe" +checksum = "9acbadc98b17aa94657122dae4b5a840c7cebe6359a5ba15d8eaa233768942a5" dependencies = [ "async-trait", "clap", diff --git a/Cargo.toml b/Cargo.toml index ea89137..1ebbcbd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ tokio = { version = "1.53.1", features = ["full"] } axum = { version = "0.8", features = ["ws", "multipart"] } axum-extra = { version = "0.12.6", features = ["cookie"] } config = "0.15.25" -sea-orm = { version = "2.0.2", features = ["sqlx-sqlite", "sqlx-postgres", "sqlx-mysql", "runtime-tokio", "with-chrono", "with-uuid", "with-json", "schema-sync"] } +sea-orm = { version = "2.0.3", features = ["sqlx-sqlite", "sqlx-postgres", "sqlx-mysql", "runtime-tokio", "with-chrono", "with-uuid", "with-json", "schema-sync"] } migration = { path = "migration" } event_bus = { path = "event_bus" } parking_lot = "0.12.5" @@ -31,7 +31,7 @@ utoipa-swagger-ui = { version = "9", features = ["axum"] } log = "0.4" bitflags = "2.13.2" argon2 = { version = "0.6.0", features = ["password-hash"] } -jsonwebtoken = { version = "11.0.0", features = ["aws_lc_rs"] } +jsonwebtoken = { version = "11.1.0", features = ["aws_lc_rs"] } tower = { version = "0.5", features = ["util"] } tower-http = { version = "0.7.1", features = ["catch-panic", "cors", "trace"] } chrono = "0.4.45" @@ -42,4 +42,4 @@ futures-util = "0.3" form_urlencoded = "1.2.2" time = "0.3.55" sha2 = "0.11.0" -rustrtc = "0.3.133" +rustrtc = "0.3.138" diff --git a/migration/Cargo.toml b/migration/Cargo.toml index 381f873..3ebb473 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -13,7 +13,7 @@ async-std = { version = "1", features = ["attributes", "tokio1"] } uuid = { version = "1", features = ["v5"] } [dependencies.sea-orm-migration] -version = "2.0.2" +version = "2.0.3" features = [ # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. diff --git a/src/routes/rtc/handlers.rs b/src/routes/rtc/handlers.rs index b337e27..2c21771 100644 --- a/src/routes/rtc/handlers.rs +++ b/src/routes/rtc/handlers.rs @@ -1,13 +1,22 @@ use crate::core::AppState; use crate::http::context::CurrentUser; +use crate::http::error::HTTPError; use crate::rtc::ws_entrypoint::ws_entrypoint_handler; -use axum::extract::{State, WebSocketUpgrade}; +use axum::extract::{Path, State, WebSocketUpgrade}; use axum::response::IntoResponse; +use uuid::Uuid; pub async fn ws_handler( ws: WebSocketUpgrade, + Path(channel_id): Path, State(state): State, CurrentUser(user): CurrentUser, -) -> impl IntoResponse { - ws.on_upgrade(move |socket| ws_entrypoint_handler(socket, state, user)) +) -> Result { + let channel = state + .repositories + .channel + .get_by_id(channel_id) + .await? + .ok_or(HTTPError::NotFound)?; + Ok(ws.on_upgrade(move |socket| ws_entrypoint_handler(socket, state, channel, user))) } diff --git a/src/routes/rtc/routes.rs b/src/routes/rtc/routes.rs index cfc4175..5465b95 100644 --- a/src/routes/rtc/routes.rs +++ b/src/routes/rtc/routes.rs @@ -4,5 +4,5 @@ use axum::Router; use axum::routing::get; pub fn router() -> Router { - Router::new().route("/rtc", get(handlers::ws_handler)) + Router::new().route("/rtc/{channel_id}", get(handlers::ws_handler)) } diff --git a/src/rtc/client.rs b/src/rtc/client.rs new file mode 100644 index 0000000..9cdea44 --- /dev/null +++ b/src/rtc/client.rs @@ -0,0 +1,35 @@ +use crate::models::{channel, user}; +use axum::extract::ws::Message; +use rustrtc::peer_connection::PeerConnection; +use std::sync::Arc; +use tokio::sync::mpsc::UnboundedSender; + +/// Client connecté à un canal RTC. +#[derive(Clone)] +pub struct RtcClient { + pub user: user::Model, + pub channel: channel::Model, + pub peer_connection: Arc, + pub websocket_sender: UnboundedSender, +} + +impl RtcClient { + pub fn new( + user: user::Model, + channel: channel::Model, + peer_connection: Arc, + websocket_sender: UnboundedSender, + ) -> Self { + Self { + user, + channel, + peer_connection, + websocket_sender, + } + } + + /// Ferme proprement la connexion WebRTC. + pub fn close(&self) { + self.peer_connection.close(); + } +} diff --git a/src/rtc/mod.rs b/src/rtc/mod.rs index 4676b4f..5ad232e 100644 --- a/src/rtc/mod.rs +++ b/src/rtc/mod.rs @@ -1,3 +1,4 @@ +mod client; mod metrics; pub mod ws_entrypoint; diff --git a/src/rtc/ws_entrypoint.rs b/src/rtc/ws_entrypoint.rs index 56138d7..649656d 100644 --- a/src/rtc/ws_entrypoint.rs +++ b/src/rtc/ws_entrypoint.rs @@ -1,7 +1,36 @@ // This is the first point when WebRTC ask for a connection +use super::client::RtcClient; use crate::core::AppState; -use crate::models::user; -use axum::extract::ws::WebSocket; +use crate::models::{channel, user}; +use axum::extract::ws::{Message, WebSocket}; +use futures_util::{SinkExt, StreamExt}; +use tokio::sync::mpsc; -pub async fn ws_entrypoint_handler(socket: WebSocket, state: AppState, user: user::Model) {} +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::(); + // todo : faire le peer connexion. + let mut rtc_client = RtcClient::new(user, channel, peer_connection, tx); + + let send_task = tokio::spawn(async move { + while let Some(message) = rx.recv().await { + if sender.send(message).await.is_err() { + break; + } + } + }); + + let client_clone = rtc_client.clone(); + let state_clone = state.clone(); + let mut recv_task = tokio::spawn(async move { + while let Some(Ok(message)) = receiver.next().await { + client_clone.on_message(message, &state_clone).await; + } + }); +}