1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! `wrtc` is a crate which wraps a [webrtc](https://webrtc.rs) library into simpler, more friendly
//! API:
//! - It offers semi-automatic connection negotiation via signal exchange.
//! - It's build around async Rust.
//! - Its primitives implement Stream trait, making them composable and reducing the amount of
//! closures and capturing that webrtc crate requires.
//!
//! Its design is partially inspired by NodeJS [SimplePeer](https://www.npmjs.com/package/simple-peer)
//! library and it offers the same message negotiation format: therefore it can be used to
//! communicate with WebRTC peers written in that library as well.
//!
//! Atm. this library is focused on Data Channels - other WebRTC primitives may be implemented in
//! the future.
//!
//! # Examples
//!
//! ```rust
//! use wrtc::{Options, Error, PeerConnection};
//! use std::sync::Arc;
//! use bytes::Bytes;
//! use futures_util::{SinkExt, StreamExt};
//! use tokio::task::JoinHandle;
//!
//! fn exchange(from: Arc<PeerConnection>, to: Arc<PeerConnection>) -> JoinHandle<Result<(), Error>> {
//! // Create a task that will exchange signals between two peers
//! // necessary to negotiate and establish connection. This part
//! // is not covered by WebRTC and may require setting up a 3rd
//! // party connection ie. via WebSockets.
//! tokio::spawn(async move {
//! while let Some(signal) = from.signal().await {
//! to.apply_signal(signal).await?;
//! }
//! Ok(())
//! })
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Error> {
//! let options = Options::with_data_channels(&["test-dc"]);
//! let initiator = Arc::new(PeerConnection::start(true, options.clone()).await?);
//! let acceptor = Arc::new(PeerConnection::start(false, options).await?);
//!
//! // setup tasks to negotiate connection between two peers
//! let _ = exchange(initiator.clone(), acceptor.clone());
//! let _ = exchange(acceptor.clone(), initiator.clone());
//!
//! // wait for connection become established
//! initiator.connected().await?;
//! acceptor.connected().await?;
//!
//! {
//! // both connections have defined only one data channel ("test-dc")
//! // so we know that the next incoming data channels belong to the same pair
//! let mut dc1 = initiator.data_channels().next().await.unwrap();
//! let mut dc2 = acceptor.data_channels().next().await.unwrap();
//!
//! // wait for the data channels to be ready
//! dc1.ready().await?;
//! dc2.ready().await?;
//!
//! assert_eq!(dc1.label(), "test-dc");
//! assert_eq!(dc2.label(), "test-dc");
//!
//! // send message from dc1 and receive it at dc2
//! let data: Bytes = "hello".into();
//! dc1.send(data.clone()).await?;
//! let msg = dc2.next().await.unwrap()?;
//! assert_eq!(msg.data, data);
//! }
//!
//! // gracefully close both peers
//! initiator.close().await?;
//! acceptor.close().await?;
//! Ok(())
//! }
//! ```
pub use DataChannel;
pub use Error;
pub use ;