feat: ✨ rtc receive offer, receive answer
This commit is contained in:
parent
f781afe995
commit
96199f71ef
4 changed files with 134 additions and 33 deletions
|
@ -23,7 +23,7 @@ web-sys = { version = "0.3.77", features = [
|
||||||
"RtcConfiguration",
|
"RtcConfiguration",
|
||||||
"RtcIceServer",
|
"RtcIceServer",
|
||||||
"RtcPeerConnection",
|
"RtcPeerConnection",
|
||||||
# "RtcSdpType",
|
"RtcSdpType",
|
||||||
"RtcSessionDescription",
|
"RtcSessionDescription",
|
||||||
"RtcSessionDescriptionInit",
|
"RtcSessionDescriptionInit",
|
||||||
"Window",
|
"Window",
|
||||||
|
|
|
@ -14,7 +14,11 @@ use leptos::{
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::HtmlAudioElement;
|
use web_sys::HtmlAudioElement;
|
||||||
|
|
||||||
use crate::{media::audio, rtc::offer, signal::start_signalling};
|
use crate::{
|
||||||
|
media::audio,
|
||||||
|
rtc::{answer, offer},
|
||||||
|
signal::start_signalling,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn app() -> impl IntoView {
|
pub fn app() -> impl IntoView {
|
||||||
let audio_stream = LocalResource::new(|| audio());
|
let audio_stream = LocalResource::new(|| audio());
|
||||||
|
@ -42,7 +46,12 @@ pub fn app() -> impl IntoView {
|
||||||
.fallback(|| button().child("Sad Button"))
|
.fallback(|| button().child("Sad Button"))
|
||||||
.build();
|
.build();
|
||||||
let username = signal(String::from(""));
|
let username = signal(String::from(""));
|
||||||
(Show(props), signalling(username), rtc(username.0))
|
(
|
||||||
|
Show(props),
|
||||||
|
signalling(username),
|
||||||
|
rtc_offer(username.0),
|
||||||
|
rtc_answer(username.0),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signalling(username: (ReadSignal<String>, WriteSignal<String>)) -> impl IntoView {
|
fn signalling(username: (ReadSignal<String>, WriteSignal<String>)) -> impl IntoView {
|
||||||
|
@ -70,16 +79,30 @@ fn signalling(username: (ReadSignal<String>, WriteSignal<String>)) -> impl IntoV
|
||||||
(signalling_server_input, signalling_submit_button)
|
(signalling_server_input, signalling_submit_button)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rtc(username: ReadSignal<String>) -> impl IntoView {
|
fn rtc_offer(username: ReadSignal<String>) -> impl IntoView {
|
||||||
let rtc_trigger = move || {
|
let offer_trigger = move || {
|
||||||
spawn_local(offer(username.get()));
|
spawn_local(offer(username.get()));
|
||||||
};
|
};
|
||||||
|
|
||||||
let rtc_start_button = button()
|
let offer_button = button()
|
||||||
.on(ev::click, move |event| {
|
.on(ev::click, move |event| {
|
||||||
event.prevent_default();
|
event.prevent_default();
|
||||||
rtc_trigger();
|
offer_trigger();
|
||||||
})
|
})
|
||||||
.child("RTC Offer");
|
.child("RTC Offer");
|
||||||
rtc_start_button
|
offer_button
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rtc_answer(username: ReadSignal<String>) -> impl IntoView {
|
||||||
|
let answer_trigger = move || {
|
||||||
|
spawn_local(answer(username.get()));
|
||||||
|
};
|
||||||
|
|
||||||
|
let answer_button = button()
|
||||||
|
.on(ev::click, move |event| {
|
||||||
|
event.prevent_default();
|
||||||
|
answer_trigger();
|
||||||
|
})
|
||||||
|
.child("RTC Answer");
|
||||||
|
answer_button
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,16 @@ pub mod gui;
|
||||||
pub mod media;
|
pub mod media;
|
||||||
pub mod rtc;
|
pub mod rtc;
|
||||||
pub mod signal;
|
pub mod signal;
|
||||||
|
|
||||||
|
pub async fn sleep(timeout: u16) {
|
||||||
|
let sleep_promise = web_sys::js_sys::Promise::new(&mut |resolve, _| {
|
||||||
|
web_sys::window()
|
||||||
|
.unwrap()
|
||||||
|
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, timeout as i32)
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
wasm_bindgen_futures::JsFuture::from(sleep_promise)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
use leptos::logging::log;
|
use leptos::logging::log;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::{
|
use web_sys::{
|
||||||
RtcConfiguration, RtcIceServer, RtcPeerConnection, RtcSessionDescriptionInit,
|
RtcConfiguration, RtcIceServer, RtcPeerConnection, RtcSdpType, RtcSessionDescriptionInit,
|
||||||
js_sys::{Array, Reflect},
|
js_sys::{Array, Reflect},
|
||||||
wasm_bindgen::{JsCast, JsValue},
|
wasm_bindgen::{JsCast, JsValue},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::signal::send_offer;
|
use crate::{
|
||||||
|
signal::{receive_answer, receive_offer, send_answer, send_offer},
|
||||||
|
sleep,
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn offer(username: String) {
|
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()
|
||||||
.collect::<Array>();
|
.collect::<Array>();
|
||||||
|
@ -17,27 +20,89 @@ pub async fn offer(username: String) {
|
||||||
let ice_servers = vec![ice_server].into_iter().collect::<Array>();
|
let ice_servers = vec![ice_server].into_iter().collect::<Array>();
|
||||||
let rtc_configuration = RtcConfiguration::new();
|
let rtc_configuration = RtcConfiguration::new();
|
||||||
rtc_configuration.set_ice_servers(&ice_servers);
|
rtc_configuration.set_ice_servers(&ice_servers);
|
||||||
let peer_connection = RtcPeerConnection::new_with_configuration(&rtc_configuration).unwrap();
|
RtcPeerConnection::new_with_configuration(&rtc_configuration).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn offer(username: String) {
|
||||||
|
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 rtc_session_offer = JsFuture::from(peer_connection_create_offer_promise)
|
let peer_connection_session_offer = JsFuture::from(peer_connection_create_offer_promise)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
log!("{:#?}", rtc_session_offer);
|
log!("{:#?}", peer_connection_session_offer);
|
||||||
let rtc_session_offer = rtc_session_offer
|
let peer_connection_session_offer = peer_connection_session_offer
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unchecked_ref::<RtcSessionDescriptionInit>();
|
.unchecked_ref::<RtcSessionDescriptionInit>();
|
||||||
log!("{:#?}", rtc_session_offer);
|
log!("{:#?}", peer_connection_session_offer);
|
||||||
JsFuture::from(peer_connection.set_local_description(rtc_session_offer))
|
JsFuture::from(peer_connection.set_local_description(peer_connection_session_offer))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let rtc_session_offer = Reflect::get(&rtc_session_offer, &JsValue::from_str("sdp"))
|
let peer_connection_session_offer =
|
||||||
|
Reflect::get(&peer_connection_session_offer, &JsValue::from_str("sdp"))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_string()
|
.as_string()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
log!("{}", rtc_session_offer);
|
log!("{}", peer_connection_session_offer);
|
||||||
let data = rtc_session_offer;
|
let data = peer_connection_session_offer;
|
||||||
|
|
||||||
send_offer(&username, &data).await.unwrap();
|
if let Err(err_val) = send_offer(&username, &data).await {
|
||||||
|
log!("Error: Send Offer | {}", err_val)
|
||||||
|
}
|
||||||
|
for _ in 0..10 {
|
||||||
|
match receive_answer(&username).await {
|
||||||
|
Ok(received_answer) => {
|
||||||
|
log!("{:#?}", received_answer);
|
||||||
|
let peer_connection_session_answer =
|
||||||
|
RtcSessionDescriptionInit::new(RtcSdpType::Answer);
|
||||||
|
peer_connection_session_answer.set_sdp(received_answer.get_data().as_str());
|
||||||
|
JsFuture::from(
|
||||||
|
peer_connection.set_remote_description(&peer_connection_session_answer),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err_val) => log!("Error: Receive Answer | {}", err_val),
|
||||||
|
}
|
||||||
|
sleep(1000).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn answer() {}
|
pub async fn answer(username: String) {
|
||||||
|
for _ in 0..10 {
|
||||||
|
match receive_offer(&username).await {
|
||||||
|
Ok(offer) => {
|
||||||
|
let peer_connection = create_peer_connection_with_configuration().await;
|
||||||
|
let peer_connection_session_offer =
|
||||||
|
RtcSessionDescriptionInit::new(RtcSdpType::Offer);
|
||||||
|
peer_connection_session_offer.set_sdp(offer.get_data().as_str());
|
||||||
|
JsFuture::from(
|
||||||
|
peer_connection.set_remote_description(&peer_connection_session_offer),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let peer_connection_create_answer_promise = peer_connection.create_answer();
|
||||||
|
let peer_connection_answer = JsFuture::from(peer_connection_create_answer_promise)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let peer_connection_answer = peer_connection_answer
|
||||||
|
.as_ref()
|
||||||
|
.unchecked_ref::<RtcSessionDescriptionInit>();
|
||||||
|
JsFuture::from(peer_connection.set_local_description(peer_connection_answer))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let session_answer = Reflect::get(&peer_connection_answer, &JsValue::from("sdp"))
|
||||||
|
.unwrap()
|
||||||
|
.as_string()
|
||||||
|
.unwrap();
|
||||||
|
log!("{}", session_answer);
|
||||||
|
let data = session_answer;
|
||||||
|
|
||||||
|
send_answer(&username, &data).await.unwrap();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err_val) => log!("Error: Receive Offer | {}", err_val),
|
||||||
|
}
|
||||||
|
sleep(1000).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue