feat: ice local and remote changes

This commit is contained in:
Ahmet Kaan Gümüş 2025-04-17 04:09:18 +03:00
parent 4f874d8789
commit 3b122dc4f7
6 changed files with 88 additions and 27 deletions

View file

@ -23,8 +23,10 @@ web-sys = { version = "0.3.77", features = [
"RtcConfiguration", "RtcConfiguration",
"RtcIceCandidate", "RtcIceCandidate",
"RtcIceCandidateInit", "RtcIceCandidateInit",
"RtcIceConnectionState",
"RtcIceServer", "RtcIceServer",
"RtcPeerConnection", "RtcPeerConnection",
"RtcPeerConnectionIceEvent",
"RtcPeerConnectionState", "RtcPeerConnectionState",
"RtcSdpType", "RtcSdpType",
"RtcSessionDescription", "RtcSessionDescription",

View file

@ -81,7 +81,9 @@ fn signalling(username: (ReadSignal<String>, WriteSignal<String>)) -> impl IntoV
fn rtc_offer(username: ReadSignal<String>) -> impl IntoView { fn rtc_offer(username: ReadSignal<String>) -> impl IntoView {
let offer_trigger = move || { let offer_trigger = move || {
spawn_local(offer(username.get())); spawn_local(async move {
let peer_connection = offer(username.get()).await;
});
}; };
let offer_button = button() let offer_button = button()
@ -95,7 +97,9 @@ fn rtc_offer(username: ReadSignal<String>) -> impl IntoView {
fn rtc_answer(username: ReadSignal<String>) -> impl IntoView { fn rtc_answer(username: ReadSignal<String>) -> impl IntoView {
let answer_trigger = move || { let answer_trigger = move || {
spawn_local(answer(username.get())); spawn_local(async move {
let peer_connection = answer(username.get()).await;
});
}; };
let answer_button = button() let answer_button = button()

View file

@ -1,16 +1,67 @@
use leptos::logging::log; use leptos::{
logging::log,
prelude::{Set, Signal, Update, Write, WriteSignal},
task::spawn_local,
};
use wasm_bindgen_futures::JsFuture; use wasm_bindgen_futures::JsFuture;
use web_sys::{ use web_sys::{
RtcConfiguration, RtcIceServer, RtcPeerConnection, RtcSdpType, RtcSessionDescriptionInit, RtcConfiguration, RtcIceCandidate, RtcIceCandidateInit, RtcIceServer, RtcPeerConnection,
RtcPeerConnectionIceEvent, RtcSdpType, RtcSessionDescriptionInit,
js_sys::{Array, Reflect}, js_sys::{Array, Reflect},
wasm_bindgen::{JsCast, JsValue}, wasm_bindgen::{JsCast, JsValue, prelude::Closure},
}; };
use crate::{ use crate::{
signal::{receive_answer, receive_offer, send_answer, send_offer}, signal::{
receive_answer, receive_ice_candidate, receive_offer, send_answer, send_ice_candidate,
send_offer,
},
sleep, sleep,
}; };
async fn local_ice_candidate_handler(username: &String, peer_connection: &RtcPeerConnection) {
let local_ice_candidate_handler: Box<dyn Fn(String, RtcPeerConnectionIceEvent)> =
Box::new(move |username, peer_connection_ice_event| {
spawn_local(async move {
{
let username: &String = &username;
async move {
sleep(1000).await;
if let Some(peer_connection_ice_candidate) =
peer_connection_ice_event.candidate()
{
let peer_connection_ice_candidate =
peer_connection_ice_candidate.as_string().unwrap();
send_ice_candidate(username, &peer_connection_ice_candidate)
.await
.unwrap();
}
}
}
.await
});
});
let local_ice_candidate_handler = Closure::wrap(local_ice_candidate_handler);
peer_connection.set_onicecandidate(Some(local_ice_candidate_handler.as_ref().unchecked_ref()));
}
async fn remote_ice_candidate_handler(username: &String, peer_connection: &RtcPeerConnection) {
if let Ok(user_and_signal) = receive_ice_candidate(username).await {
let peer_connection_ice_candidate_init =
RtcIceCandidateInit::new(&user_and_signal.signal.get_data());
let peer_connection_ice_candidate =
RtcIceCandidate::new(&peer_connection_ice_candidate_init).unwrap();
let peer_connection_add_ice_candidate_promise = peer_connection
.add_ice_candidate_with_opt_rtc_ice_candidate(Some(&peer_connection_ice_candidate));
JsFuture::from(peer_connection_add_ice_candidate_promise)
.await
.unwrap();
}
}
async fn create_peer_connection_with_configuration() -> RtcPeerConnection { async fn create_peer_connection_with_configuration() -> RtcPeerConnection {
let ice_server_addresses = vec![JsValue::from("stun:stun.l.google.com:19302")] let ice_server_addresses = vec![JsValue::from("stun:stun.l.google.com:19302")]
.into_iter() .into_iter()
@ -23,7 +74,7 @@ async fn create_peer_connection_with_configuration() -> RtcPeerConnection {
RtcPeerConnection::new_with_configuration(&rtc_configuration).unwrap() RtcPeerConnection::new_with_configuration(&rtc_configuration).unwrap()
} }
pub async fn offer(username: String) { pub async fn offer(username: String) -> RtcPeerConnection {
let peer_connection = create_peer_connection_with_configuration().await; let peer_connection = create_peer_connection_with_configuration().await;
let peer_connection_create_offer_promise = peer_connection.create_offer(); let peer_connection_create_offer_promise = peer_connection.create_offer();
let peer_connection_session_offer = JsFuture::from(peer_connection_create_offer_promise) let peer_connection_session_offer = JsFuture::from(peer_connection_create_offer_promise)
@ -49,7 +100,7 @@ pub async fn offer(username: String) {
log!("Error: Send Offer | {}", err_val) log!("Error: Send Offer | {}", err_val)
} }
for _ in 0..10 { loop {
match receive_answer(&username).await { match receive_answer(&username).await {
Ok(received_user_and_signal_answer) => { Ok(received_user_and_signal_answer) => {
log!("{:#?}", received_user_and_signal_answer); log!("{:#?}", received_user_and_signal_answer);
@ -57,17 +108,18 @@ pub async fn offer(username: String) {
RtcSessionDescriptionInit::new(RtcSdpType::Answer); RtcSessionDescriptionInit::new(RtcSdpType::Answer);
peer_connection_session_answer peer_connection_session_answer
.set_sdp(received_user_and_signal_answer.signal.get_data().as_str()); .set_sdp(received_user_and_signal_answer.signal.get_data().as_str());
sleep(1000).await;
JsFuture::from( JsFuture::from(
peer_connection.set_remote_description(&peer_connection_session_answer), peer_connection.set_remote_description(&peer_connection_session_answer),
) )
.await .await
.unwrap(); .unwrap();
for _ in 0..100 { log!("{:#?}", peer_connection.connection_state());
log!("{:#?}", peer_connection.connection_state()); log!("{:#?}", peer_connection.ice_connection_state());
sleep(1000).await;
} local_ice_candidate_handler(&username, &peer_connection).await;
break; return peer_connection;
} }
Err(err_val) => log!("Error: Receive Answer | {}", err_val), Err(err_val) => log!("Error: Receive Answer | {}", err_val),
} }
@ -75,10 +127,11 @@ pub async fn offer(username: String) {
} }
} }
pub async fn answer(username: String) { pub async fn answer(username: String) -> RtcPeerConnection {
for _ in 0..10 { loop {
match receive_offer(&username).await { match receive_offer(&username).await {
Ok(received_user_and_signal_offer) => { Ok(received_user_and_signal_offer) => {
log!("{:#?}", received_user_and_signal_offer);
let peer_connection = create_peer_connection_with_configuration().await; let peer_connection = create_peer_connection_with_configuration().await;
let peer_connection_session_offer = let peer_connection_session_offer =
RtcSessionDescriptionInit::new(RtcSdpType::Offer); RtcSessionDescriptionInit::new(RtcSdpType::Offer);
@ -107,12 +160,12 @@ pub async fn answer(username: String) {
let data = session_answer; let data = session_answer;
send_answer(&username, &data).await.unwrap(); send_answer(&username, &data).await.unwrap();
log!("{:#?}", peer_connection.connection_state());
log!("{:#?}", peer_connection.ice_connection_state());
for _ in 0..100 { local_ice_candidate_handler(&username, &peer_connection).await;
log!("{:#?}", peer_connection.connection_state());
sleep(1000).await; return peer_connection;
}
break;
} }
Err(err_val) => log!("Error: Receive Offer | {}", err_val), Err(err_val) => log!("Error: Receive Offer | {}", err_val),
} }

View file

@ -14,7 +14,7 @@ impl UserAndSignal {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct User { pub struct User {
pub username: String, pub username: String,
} }

View file

@ -20,10 +20,9 @@ async fn extract_user_from_authorization_header(headers: &HeaderMap) -> Option<U
dbg!(authorization_header); dbg!(authorization_header);
if let Ok(authorization_header) = authorization_header.to_str() { if let Ok(authorization_header) = authorization_header.to_str() {
if let Some((bearer, authorization_token)) = authorization_header.split_once(' ') { if let Some((bearer, authorization_token)) = authorization_header.split_once(' ') {
dbg!( println!(
"Info: Verify | Http Header | {} || {}", "Info: Extraction | Authorization Header | {} || {}",
bearer, bearer, authorization_token
authorization_token
); );
if bearer.to_lowercase() == "bearer" { if bearer.to_lowercase() == "bearer" {
let user = User { let user = User {
@ -39,7 +38,7 @@ async fn extract_user_from_authorization_header(headers: &HeaderMap) -> Option<U
pub async fn verify_then_get_user(mut request: Request, next: Next) -> impl IntoResponse { pub async fn verify_then_get_user(mut request: Request, next: Next) -> impl IntoResponse {
let headers = request.headers(); let headers = request.headers();
dbg!(headers); println!("Info: Verify | Headers| {:#?}", headers);
if let Some(user) = extract_user_from_authorization_header(headers).await { if let Some(user) = extract_user_from_authorization_header(headers).await {
let user = Arc::new(user); let user = Arc::new(user);
request.extensions_mut().insert(user); request.extensions_mut().insert(user);

View file

@ -57,13 +57,16 @@ async fn create_signal(
StatusCode::OK StatusCode::OK
} }
#[debug_handler]
async fn read_signal( async fn read_signal(
Extension(user_and_expected_signal): Extension<Arc<UserAndExpectedSignal>>, Extension(user_and_expected_signal): Extension<Arc<UserAndExpectedSignal>>,
) -> impl IntoResponse { ) -> impl IntoResponse {
let mut target_index = None; let mut target_index = None;
let mut json_body = serde_json::json!(""); let mut json_body = serde_json::json!("");
for (index, user_and_signal) in USERS_AND_SIGNALS.read().unwrap().iter().enumerate() { for (index, user_and_signal) in USERS_AND_SIGNALS.read().unwrap().iter().enumerate() {
if user_and_signal.signal.get_signal_type() == user_and_expected_signal.expected_signal { if user_and_signal.signal.get_signal_type() == user_and_expected_signal.expected_signal
&& user_and_signal.user != user_and_expected_signal.user
{
json_body = serde_json::json!(user_and_signal); json_body = serde_json::json!(user_and_signal);
target_index = Some(index); target_index = Some(index);
} }