Rust wrappers for libdatachannel, a WebRTC Data Channels standalone implementation in C++.
This crate provides two traits that end user must implement, DataChannelHandler
and
PeerConnectionHandler
, which defined all callbacks for RtcPeerConnection
and
RtcDataChannel
structs respectively.
Aforementioned traits are defined as follows:
```rust pub trait DataChannelHandler { fn onopen(&mut self) {} fn onclosed(&mut self) {} fn onerror(&mut self, err: &str) {} fn onmessage(&mut self, msg: &[u8]) {} fn onbufferedamountlow(&mut self) {} fn onavailable(&mut self) {} }
pub trait PeerConnectionHandler { type DCH;
fn data_channel_handler(&mut self, info: DataChannelInfo) -> Self::DCH;
fn on_description(&mut self, sess_desc: SessionDescription) {}
fn on_candidate(&mut self, cand: IceCandidate) {}
fn on_connection_state_change(&mut self, state: ConnectionState) {}
fn on_gathering_state_change(&mut self, state: GatheringState) {}
fn on_data_channel(&mut self, data_channel: Box<RtcDataChannel<Self::DCH>>) {}
} ```
Note that all on_*
methods have a default no-operation implementation.
The main struct, RtcPeerconnection
, takes a RtcConfig
(which defines ICE servers)
and a instance of PeerConnectionHandler
.
Here is the basic workflow:
```rust use datachannel::{DataChannelHandler, DataChannelInfo, PeerConnectionHandler, RtcConfig, RtcPeerConnection};
struct MyChannel;
impl DataChannelHandler for MyChannel { fn on_open(&mut self) { // TODO: notify that the data channel is ready (optional) }
fn on_message(&mut self, msg: &[u8]) {
// TODO: process the received message
}
}
struct MyConnection;
impl PeerConnectionHandler for MyConnection { type DCH = MyChannel;
/// Used to create the `RtcDataChannel` received through `on_data_channel`.
fn data_channel_handler(&mut self, _info: DataChannelInfo) -> Self::DCH {
MyChannel
}
fn on_data_channel(&mut self, mut dc: Box<RtcDataChannel<Self::DCH>>) {
// TODO: store `dc` to keep receiving its messages (otherwise it will be dropped)
}
}
let iceservers = vec!["stun:stun.l.google.com:19302"]; let conf = RtcConfig::new(&iceservers);
let mut pc = RtcPeerConnection::new(&conf, MyConnection)?;
let mut dc = pc.createdatachannel("test-dc", MyChannel)?;
// TODO: exchange SessionDescription
and IceCandidate
with remote peer
// TODO: wait for dc
to be opened (should be signaled through on_open
)
// ...
// Then send a message
dc.send("Hello Peer!".as_bytes())?;
```
Complete implementation example can be found in the tests.
See also async-datachannel for an async-based implementation.
log
crate (mutually exclusive with
tracing).tracing
crate (mutally exclusive with
log).OpenSSL
).libdatachannel
.Note that CMake
is required to compile libdatachannel through
datachannel-sys.
Clone the repo recursively:
sh
git clone --recursive https://github.com/lerouxrgd/datachannel-rs.git
You probably need to set the following environment variables if your build fails with an
OpenSSL
related error.
sh
export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl@1.1/1.1.1i/
export OPENSSL_LIBRARIES=/usr/local/Cellar/openssl@1.1/1.1.1i/lib
With the paths of your local OpenSSL
installation.
Required dependencies:
```sh
sudo apt install build-essential cmake pkg-config libssl-dev clang ```