use crate::utils::{create_sdp_answer, create_sdp_offer, IceCandidate};
use ::log::{debug, error, info};
use wasm_peers_protocol::one_to_one::SignalMessage;
use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;
use web_sys::{
RtcIceCandidate, RtcIceCandidateInit, RtcPeerConnection, RtcSdpType, RtcSessionDescriptionInit,
WebSocket,
};
pub(crate) async fn handle_websocket_message(
message: SignalMessage,
peer_connection: RtcPeerConnection,
websocket: WebSocket,
) -> Result<(), JsValue> {
match message {
SignalMessage::SessionJoin(_session_id) => {
error!("error, SessionStartOrJoin should only be sent by peers to signaling server");
}
SignalMessage::SessionReady(session_id, is_host) => {
info!("peer received info that session is ready {:?}", session_id);
if is_host {
let offer = create_sdp_offer(&peer_connection).await?;
let signal_message = SignalMessage::SdpOffer(session_id.clone(), offer);
let signal_message = serde_json_wasm::to_string(&signal_message)
.expect("failed to serialize SignalMessage");
websocket.send_with_str(&signal_message)?;
debug!("(is_host: {}) sent an offer successfully", is_host);
}
}
SignalMessage::SdpOffer(session_id, offer) => {
let answer = create_sdp_answer(&peer_connection, offer)
.await
.expect("failed to create SDP answer");
debug!("received an offer and created an answer: {}", answer);
let signal_message = SignalMessage::SdpAnswer(session_id, answer);
let signal_message = serde_json_wasm::to_string(&signal_message)
.expect("failed to serialize SignalMessage");
websocket
.send_with_str(&signal_message)
.expect("failed to send SPD answer to signaling server");
}
SignalMessage::SdpAnswer(session_id, answer) => {
let mut remote_session_description = RtcSessionDescriptionInit::new(RtcSdpType::Answer);
remote_session_description.sdp(&answer);
JsFuture::from(peer_connection.set_remote_description(&remote_session_description))
.await
.expect("failed to set remote descripiton");
debug!(
"received answer from peer and set remote description: {}, {:?}",
answer, session_id
);
}
SignalMessage::IceCandidate(_session_id, ice_candidate) => {
debug!("peer received ice candidate: {}", &ice_candidate);
let ice_candidate = serde_json_wasm::from_str::<IceCandidate>(&ice_candidate)
.expect("failed to deserialize IceCandidate");
let mut rtc_candidate = RtcIceCandidateInit::new("");
rtc_candidate.candidate(&ice_candidate.candidate);
rtc_candidate.sdp_m_line_index(ice_candidate.sdp_m_line_index);
rtc_candidate.sdp_mid(ice_candidate.sdp_mid.as_deref());
let rtc_candidate =
RtcIceCandidate::new(&rtc_candidate).expect("failed to create new RtcIceCandidate");
JsFuture::from(
peer_connection.add_ice_candidate_with_opt_rtc_ice_candidate(Some(&rtc_candidate)),
)
.await
.expect("failed to add ICE candidate");
debug!("added ice candidate {:?}", ice_candidate);
}
SignalMessage::Error(session_id, error) => {
error!(
"signaling server returned error: session id: {:?}, error:{}",
session_id, error
);
}
}
Ok(())
}