Skip to content

Commit 745ef06

Browse files
authored
Implementation of data channels on top of webrtc data channels (#77)
1 parent 43e79b6 commit 745ef06

19 files changed

+1048
-67
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ set(HEADER_FILES
6060
set(
6161
SOURCE_FILES
6262
src/Consumer.cpp
63+
src/DataConsumer.cpp
64+
src/DataProducer.cpp
6365
src/Device.cpp
6466
src/Handler.cpp
6567
src/Logger.cpp

include/DataConsumer.hpp

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#ifndef MSC_DATACONSUMER_HPP
2+
#define MSC_DATACONSUMER_HPP
3+
4+
#include <json.hpp>
5+
#include <api/data_channel_interface.h>
6+
#include <string>
7+
8+
namespace mediasoupclient
9+
{
10+
class RecvTransport;
11+
12+
class DataConsumer : public webrtc::DataChannelObserver
13+
{
14+
public:
15+
class PrivateListener
16+
{
17+
public:
18+
virtual void OnClose(DataConsumer* dataConsumer) = 0;
19+
};
20+
21+
class Listener
22+
{
23+
public:
24+
// DataChannel state changes.
25+
virtual void OnConnecting(DataConsumer* dataConsumer) = 0;
26+
virtual void OnOpen(DataConsumer* dataConsumer) = 0;
27+
virtual void OnClosing(DataConsumer* dataConsumer) = 0;
28+
virtual void OnClose(DataConsumer* dataConsumer) = 0;
29+
30+
// A data buffer was successfully received.
31+
virtual void OnMessage(DataConsumer* dataConsumer, const webrtc::DataBuffer& buffer) = 0;
32+
33+
virtual void OnTransportClose(DataConsumer* dataConsumer) = 0;
34+
};
35+
36+
private:
37+
DataConsumer(
38+
Listener* listener,
39+
PrivateListener* privateListener,
40+
const std::string& id,
41+
const std::string& dataProducerId,
42+
rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel,
43+
const nlohmann::json& sctpStreamParameters,
44+
const nlohmann::json& appData);
45+
46+
public:
47+
const std::string& GetId() const;
48+
std::string GetLocalId() const;
49+
const std::string& GetDataProducerId() const;
50+
const nlohmann::json& GetSctpStreamParameters() const;
51+
webrtc::DataChannelInterface::DataState GetReadyState() const;
52+
std::string GetLabel() const;
53+
std::string GetProtocol() const;
54+
const nlohmann::json& GetAppData() const;
55+
bool IsClosed() const;
56+
void Close();
57+
58+
private:
59+
void TransportClosed();
60+
61+
// RecvTransport will create instances and call private member TransporClosed.
62+
friend RecvTransport;
63+
64+
private:
65+
Listener* listener;
66+
PrivateListener* privateListener;
67+
std::string id;
68+
std::string dataProducerId;
69+
rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel;
70+
bool closed{ false };
71+
nlohmann::json sctpParameters;
72+
nlohmann::json appData;
73+
74+
/* Virtual methods inherited from webrtc::DataChannelObserver. */
75+
public:
76+
// The data channel state has changed.
77+
void OnStateChange() override;
78+
// A data buffer was successfully received.
79+
void OnMessage(const webrtc::DataBuffer& buffer) override;
80+
// The data channel's buffered_amount has changed.
81+
void OnBufferedAmountChange(uint64_t sentDataSize) override;
82+
};
83+
} // namespace mediasoupclient
84+
85+
#endif

include/DataProducer.hpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#ifndef MSC_DATAPRODUCER_HPP
2+
#define MSC_DATAPRODUCER_HPP
3+
4+
#include "Handler.hpp"
5+
#include <json.hpp>
6+
#include <api/data_channel_interface.h>
7+
#include <string>
8+
9+
namespace mediasoupclient
10+
{
11+
class SendTransport;
12+
13+
class DataProducer : public webrtc::DataChannelObserver
14+
{
15+
public:
16+
class PrivateListener
17+
{
18+
public:
19+
virtual void OnClose(DataProducer* dataProducer) = 0;
20+
};
21+
22+
/* Public Listener API */
23+
class Listener
24+
{
25+
public:
26+
// DataChannel state changes.
27+
virtual void OnOpen(DataProducer* dataProducer) = 0;
28+
virtual void OnClose(DataProducer* dataProducer) = 0;
29+
virtual void OnBufferedAmountChange(DataProducer* dataProducer, uint64_t sentDataSize) = 0;
30+
31+
virtual void OnTransportClose(DataProducer* dataProducer) = 0;
32+
};
33+
34+
private:
35+
PrivateListener* privateListener;
36+
Listener* listener;
37+
std::string id;
38+
rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel;
39+
bool closed;
40+
nlohmann::json sctpStreamParameters;
41+
nlohmann::json appData;
42+
void TransportClosed();
43+
44+
friend SendTransport;
45+
46+
private:
47+
DataProducer(
48+
DataProducer::PrivateListener* privateListener,
49+
DataProducer::Listener* listener,
50+
const std::string& id,
51+
rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel,
52+
const nlohmann::json& sctpStreamParameters,
53+
const nlohmann::json& appData);
54+
55+
public:
56+
const std::string& GetId() const;
57+
std::string GetLocalId() const;
58+
const nlohmann::json& GetSctpStreamParameters() const;
59+
webrtc::DataChannelInterface::DataState GetReadyState() const;
60+
std::string GetLabel();
61+
std::string GetProtocol();
62+
uint64_t GetBufferedAmount() const;
63+
const nlohmann::json& GetAppData() const;
64+
bool IsClosed() const;
65+
void Close();
66+
void Send(const webrtc::DataBuffer& buffer);
67+
68+
/* Virtual methods inherited from webrtc::DataChannelObserver. */
69+
public:
70+
void OnStateChange() override;
71+
// A data buffer was successfully received.
72+
void OnMessage(const webrtc::DataBuffer& buffer) override;
73+
// The data channel's buffered_amount has changed.
74+
void OnBufferedAmountChange(uint64_t sentDataSize) override;
75+
};
76+
} // namespace mediasoupclient
77+
78+
#endif

include/Handler.hpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ namespace mediasoupclient
2626
webrtc::PeerConnectionInterface::IceConnectionState connectionState) = 0;
2727
};
2828

29+
public:
30+
struct DataChannel
31+
{
32+
std::string localId;
33+
rtc::scoped_refptr<webrtc::DataChannelInterface> dataChannel;
34+
nlohmann::json sctpStreamParameters;
35+
};
36+
2937
public:
3038
static nlohmann::json GetNativeRtpCapabilities(
3139
const PeerConnection::Options* peerConnectionOptions = nullptr);
@@ -47,8 +55,7 @@ namespace mediasoupclient
4755
virtual void RestartIce(const nlohmann::json& iceParameters) = 0;
4856

4957
protected:
50-
void SetupTransport(
51-
const std::string& localDtlsRole, nlohmann::json localSdpObject = nlohmann::json::object());
58+
void SetupTransport(const std::string& localDtlsRole, nlohmann::json& localSdpObject);
5259

5360
/* Methods inherited from PeerConnectionListener. */
5461
public:
@@ -58,19 +65,21 @@ namespace mediasoupclient
5865
// PrivateListener instance.
5966
PrivateListener* privateListener{ nullptr };
6067
// Remote SDP instance.
61-
std::unique_ptr<Sdp::RemoteSdp> remoteSdp;
68+
std::unique_ptr<Sdp::RemoteSdp> remoteSdp{ nullptr };
6269
// Got transport local and remote parameters.
6370
bool transportReady{ false };
6471
// Map of RTCTransceivers indexed by MID.
65-
std::unordered_map<std::string, webrtc::RtpTransceiverInterface*> mapMidTransceiver;
72+
std::unordered_map<std::string, webrtc::RtpTransceiverInterface*> mapMidTransceiver{};
6673
// PeerConnection instance.
67-
std::unique_ptr<PeerConnection> pc;
74+
std::unique_ptr<PeerConnection> pc{ nullptr };
75+
bool hasDataChannelMediaSection = false;
76+
uint32_t nextSendSctpStreamId = 0;
6877
};
6978

7079
class SendHandler : public Handler
7180
{
7281
public:
73-
struct SendData
82+
struct SendResult
7483
{
7584
std::string localId;
7685
webrtc::RtpSenderInterface* rtpSender{ nullptr };
@@ -89,7 +98,7 @@ namespace mediasoupclient
8998
const nlohmann::json& sendingRemoteRtpParametersByKind = nlohmann::json());
9099

91100
public:
92-
SendData Send(
101+
SendResult Send(
93102
webrtc::MediaStreamTrackInterface* track,
94103
std::vector<webrtc::RtpEncodingParameters>* encodings,
95104
const nlohmann::json* codecOptions);
@@ -98,6 +107,7 @@ namespace mediasoupclient
98107
void SetMaxSpatialLayer(const std::string& localId, uint8_t spatialLayer);
99108
nlohmann::json GetSenderStats(const std::string& localId);
100109
void RestartIce(const nlohmann::json& iceParameters) override;
110+
DataChannel SendDataChannel(const std::string& label, webrtc::DataChannelInit dataChannelInit);
101111

102112
private:
103113
// Generic sending RTP parameters for audio and video.
@@ -110,7 +120,7 @@ namespace mediasoupclient
110120
class RecvHandler : public Handler
111121
{
112122
public:
113-
struct RecvData
123+
struct RecvResult
114124
{
115125
std::string localId;
116126
webrtc::RtpReceiverInterface* rtpReceiver{ nullptr };
@@ -126,10 +136,12 @@ namespace mediasoupclient
126136
const nlohmann::json& sctpParameters,
127137
const PeerConnection::Options* peerConnectionOptions);
128138

129-
RecvData Receive(const std::string& id, const std::string& kind, const nlohmann::json* rtpParameters);
139+
RecvResult Receive(
140+
const std::string& id, const std::string& kind, const nlohmann::json* rtpParameters);
130141
void StopReceiving(const std::string& localId);
131142
nlohmann::json GetReceiverStats(const std::string& localId);
132143
void RestartIce(const nlohmann::json& iceParameters) override;
144+
DataChannel ReceiveDataChannel(const std::string& label, webrtc::DataChannelInit dataChannelInit);
133145
};
134146
} // namespace mediasoupclient
135147

include/PeerConnection.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ namespace mediasoupclient
130130
nlohmann::json GetStats();
131131
nlohmann::json GetStats(rtc::scoped_refptr<webrtc::RtpSenderInterface> selector);
132132
nlohmann::json GetStats(rtc::scoped_refptr<webrtc::RtpReceiverInterface> selector);
133+
rtc::scoped_refptr<webrtc::DataChannelInterface> CreateDataChannel(
134+
const std::string& label, const webrtc::DataChannelInit* config);
133135

134136
private:
135137
// Signaling and worker threads.

include/Producer.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace mediasoupclient
6464
private:
6565
void TransportClosed();
6666

67-
/* SendTransport will create instances and call private member TransporClosed */
67+
/* SendTransport will create instances and call private member TransportClosed */
6868
friend SendTransport;
6969

7070
private:

0 commit comments

Comments
 (0)