Skip to content
WebRTC DataChannels C++ standalone implementation
C++ CMake C Makefile
Branch: master
Clone or download

libdatachannel - C/C++ WebRTC DataChannels

libdatachannel is a standalone implementation of WebRTC DataChannels in C++17 with C bindings. It enables direct connectivity between native applications and web browsers without the pain of importing the entire WebRTC stack. Its API is modelled as a simplified version of the JavaScript WebRTC API, in order to ease the design of cross-environment applications.

This projet is originally inspired by librtcdcpp, however it is a complete rewrite from scratch, because the messy architecture of librtcdcpp made solving its implementation issues difficult.

Licensed under LGPLv2, see LICENSE.


The library aims at fully implementing SCTP DataChannels (draft-ietf-rtcweb-data-channel-13) over DTLS/UDP (RFC7350) and has been tested to be compatible with Firefox and Chromium. It supports IPv6 and Multicast DNS candidates resolution (draft-ietf-rtcweb-mdns-ice-candidates-03) provided the operating system also supports it.




$ git submodule update --init --recursive
$ mkdir build
$ cd build
$ cmake ..
$ make


In the following example, note the callbacks are called in another thread.

Signal a PeerConnection

#include "rtc/rtc.hpp"
rtc::Configuration config;

auto pc = make_shared<rtc::PeerConnection>(config);

pc->onLocalDescription([](const rtc::Description &sdp) {
    // Send the SDP to the remote peer

pc->onLocalCandidate([](const rtc::Candidate &candidate) {
    // Send the candidate to the remote peer
    MY_SEND_CANDIDATE_TO_REMOTE(candidate.candidate(), candidate.mid());


MY_ON_RECV_CANDIDATE_FROM_REMOTE([pc](string candidate, string mid) {
    pc->addRemoteCandidate(rtc::Candidate(candidate, mid));

Observe the PeerConnection state

pc->onStateChanged([](PeerConnection::State state) {
    cout << "State: " << state << endl;

pc->onGatheringStateChanged([](PeerConnection::GatheringState state) {
    cout << "Gathering state: " << state << endl;

Create a DataChannel

auto dc = pc->createDataChannel("test");
dc->onOpen([]() {
    cout << "Open" << endl;
dc->onMessage([](const variant<binary, string> &message) {
    if (holds_alternative<string>(message)) {
        cout << "Received: " << get<string>(message) << endl;

Receive a DataChannel

shared_ptr<rtc::DataChannel> dc;
pc->onDataChannel([&dc](shared_ptr<rtc::DataChannel> incoming) {
    dc = incoming;
    dc->send("Hello world!");

See test/main.cpp for a complete local connection example.

You can’t perform that action at this time.