diff options
author | metamuffin <metamuffin@disroot.org> | 2022-09-14 19:27:49 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2022-09-14 19:27:49 +0200 |
commit | 970a6cde6ac1d5431f9fc96e98944f0e7b4fd90a (patch) | |
tree | 470389d27d1a0149655e89b06eaf0aba02faf9b4 /client-native-rift/src/peer.rs | |
parent | 401ee1336f83a9172b0cc4231b382c6a099bb66c (diff) | |
download | keks-meet-970a6cde6ac1d5431f9fc96e98944f0e7b4fd90a.tar keks-meet-970a6cde6ac1d5431f9fc96e98944f0e7b4fd90a.tar.bz2 keks-meet-970a6cde6ac1d5431f9fc96e98944f0e7b4fd90a.tar.zst |
data channel working
Diffstat (limited to 'client-native-rift/src/peer.rs')
-rw-r--r-- | client-native-rift/src/peer.rs | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/client-native-rift/src/peer.rs b/client-native-rift/src/peer.rs new file mode 100644 index 0000000..22acffd --- /dev/null +++ b/client-native-rift/src/peer.rs @@ -0,0 +1,168 @@ +use std::sync::Arc; + +use log::info; +use webrtc::{ + data_channel::data_channel_message::DataChannelMessage, + ice_transport::{ice_candidate::RTCIceCandidate, ice_server::RTCIceServer}, + peer_connection::{ + configuration::RTCConfiguration, peer_connection_state::RTCPeerConnectionState, + sdp::session_description::RTCSessionDescription, RTCPeerConnection, + }, +}; + +use crate::{ + protocol::{self, RTCSessionDescriptionInit, RelayMessage}, + state::State, + Action, +}; + +pub struct Peer { + state: Arc<State>, // maybe use Weak later + peer_connection: RTCPeerConnection, + id: usize, +} + +impl Peer { + pub async fn create(state: Arc<State>, id: usize) -> Arc<Self> { + info!("({id}) peer joined"); + let config = RTCConfiguration { + ice_servers: vec![RTCIceServer { + urls: vec!["stun:metamuffin.org:16900".to_owned()], + ..Default::default() + }], + ..Default::default() + }; + + let peer_connection = state.api.new_peer_connection(config).await.unwrap(); + + let peer = Arc::new(Self { + peer_connection, + id, + state: state.clone(), + }); + peer.peer_connection + .on_peer_connection_state_change(Box::new(move |s: RTCPeerConnectionState| { + println!("conn state: {s}"); + Box::pin(async {}) + })) + .await; + + { + let peer2 = peer.clone(); + peer.peer_connection + .on_ice_candidate(box move |c| { + let peer = peer2.clone(); + Box::pin(async move { + if let Some(c) = c { + peer.on_ice_candidate(c).await + } + }) + }) + .await; + } + + { + let peer2 = peer.clone(); + peer.peer_connection + .on_negotiation_needed(box move || { + let peer = peer2.clone(); + Box::pin(async { peer.on_negotiation_needed().await }) + }) + .await; + } + + if let Action::Send { .. } = &peer.state.args.action { + peer.start_transfer().await + } + + peer + } + + pub async fn send_relay(&self, inner: RelayMessage) { + self.state.send_relay(self.id, inner).await + } + + pub async fn start_transfer(&self) { + info!("starting data channel"); + let data_channel = self + .peer_connection + .create_data_channel("file-transfer", None) + .await + .unwrap(); + + data_channel + .on_message(Box::new(move |msg: DataChannelMessage| { + let msg_str = String::from_utf8(msg.data.to_vec()).unwrap(); + println!("message! '{}'", msg_str); + Box::pin(async {}) + })) + .await; + } + + pub async fn on_relay(&self, p: RelayMessage) { + match p { + protocol::RelayMessage::Offer(o) => self.on_offer(o).await, + protocol::RelayMessage::Answer(a) => self.on_answer(a).await, + protocol::RelayMessage::IceCandidate(c) => { + info!("received ICE candidate"); + self.peer_connection.add_ice_candidate(c).await.unwrap(); + } + } + } + + pub async fn on_ice_candidate(&self, candidate: RTCIceCandidate) { + self.send_relay(RelayMessage::IceCandidate( + candidate.to_json().await.unwrap(), + )) + .await; + } + + pub async fn on_negotiation_needed(self: Arc<Self>) { + info!("({}) negotiation needed", self.id); + self.offer().await + } + + pub async fn offer(&self) { + info!("sending offer"); + let offer = self.peer_connection.create_offer(None).await.unwrap(); + self.peer_connection + .set_local_description(offer.clone()) + .await + .unwrap(); + self.send_relay(protocol::RelayMessage::Offer(RTCSessionDescriptionInit { + sdp: offer.sdp, + ty: offer.sdp_type, + })) + .await + } + pub async fn on_offer(&self, offer: RTCSessionDescriptionInit) { + info!("received offer"); + let offer = RTCSessionDescription::offer(offer.sdp).unwrap(); + self.peer_connection + .set_remote_description(offer) + .await + .unwrap(); + self.answer().await + } + pub async fn answer(&self) { + info!("sending answer"); + let offer = self.peer_connection.create_answer(None).await.unwrap(); + self.peer_connection + .set_local_description(offer.clone()) + .await + .unwrap(); + self.send_relay(protocol::RelayMessage::Answer(RTCSessionDescriptionInit { + sdp: offer.sdp, + ty: offer.sdp_type, + })) + .await + } + pub async fn on_answer(&self, answer: RTCSessionDescriptionInit) { + info!("received answer"); + let offer = RTCSessionDescription::answer(answer.sdp).unwrap(); + self.peer_connection + .set_remote_description(offer) + .await + .unwrap(); + } +} |