antenna_client_web/peer/
mod.rs1use std::{cell::RefCell, collections::HashSet, rc::Rc};
2
3use crate::{Driver, JsEventCallback, Storage};
4use antenna_client_shared::{Event, IceServerConfig, RtcCallbacks, STORAGE_IDENTITY_KEY};
5use antenna_protocol::{PeerID, UserMsgPayload};
6use anyhow::Result;
7use wasm_bindgen::closure::Closure;
8
9pub struct Peer<Msg>
11where
12 Msg: UserMsgPayload + 'static,
13{
14 driver: Rc<RefCell<Driver<Msg>>>,
15 callbacks: Rc<RefCell<RtcCallbacks<Msg>>>,
16 _callback_buffer: Vec<JsEventCallback>,
17}
18
19impl<Msg> Drop for Peer<Msg>
20where
21 Msg: UserMsgPayload + 'static,
22{
23 fn drop(&mut self) {
24 self.leave();
25 }
26}
27
28impl<Msg> Default for Peer<Msg>
29where
30 Msg: UserMsgPayload + 'static,
31{
32 fn default() -> Self {
33 Self::new()
34 }
35}
36
37impl<Msg> Peer<Msg>
38where
39 Msg: UserMsgPayload + 'static,
40{
41 pub fn new() -> Self {
42 Self::with_ice_servers(IceServerConfig::default_stun())
43 }
44
45 pub fn with_ice_servers(ice_servers: Vec<IceServerConfig>) -> Self {
46 Self::with_storage(ice_servers, Storage::new(STORAGE_IDENTITY_KEY))
47 }
48
49 pub fn with_storage(ice_servers: Vec<IceServerConfig>, storage: Storage) -> Self {
50 let callbacks = Rc::new(RefCell::new(RtcCallbacks::new()));
51 let driver = Rc::new(RefCell::new(Driver::new(
52 ice_servers,
53 callbacks.clone(),
54 storage,
55 )));
56
57 let window = web_sys::window().expect("no global window");
58 let cb = Closure::<dyn FnMut()>::new({
59 let driver = driver.clone();
60 move || {
61 Driver::leave(driver.clone());
62 }
63 });
64 let _callback_buffer = vec![JsEventCallback::new(window.into(), "beforeunload", cb)];
65
66 Self {
67 driver,
68 callbacks,
69 _callback_buffer,
70 }
71 }
72
73 pub fn my_id(&self) -> PeerID {
74 *self.driver.borrow().id()
75 }
76
77 pub fn subscribe(&self, subscription: Event<Msg>) -> u64 {
78 self.callbacks.borrow_mut().subscribe(subscription)
79 }
80
81 pub fn unsubscribe(&self, id: u64) -> bool {
82 self.callbacks.borrow_mut().unsubscribe(id)
83 }
84
85 pub async fn start(&self) -> Result<String> {
86 Driver::start(self.driver.clone()).await
87 }
88
89 pub async fn receive_offer(&self, offer: &str) -> Result<String> {
90 Driver::receive_offer(self.driver.clone(), offer).await
91 }
92
93 pub async fn receive_answer(&self, answer: &str) -> Result<()> {
94 Driver::receive_answer(self.driver.clone(), answer).await
95 }
96
97 pub fn send(&self, peer_id: PeerID, data: Msg) {
98 Driver::send(self.driver.clone(), peer_id, data);
99 }
100
101 pub fn broadcast(&self, data: Msg) {
102 Driver::broadcast(self.driver.clone(), data);
103 }
104
105 pub fn leave(&self) {
106 Driver::leave(self.driver.clone());
107 }
108
109 pub fn is_connected(&self, peer_id: PeerID) -> bool {
110 self.driver.borrow().is_connected(&peer_id)
111 }
112
113 pub fn connected_peers(&self) -> HashSet<String> {
114 self.driver
115 .borrow()
116 .connected_peers()
117 .iter()
118 .map(|p| p.to_string())
119 .collect()
120 }
121}