node-datachannel 0.28.0 → 0.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.clang-format +17 -0
- package/.prettierignore +3 -0
- package/API.md +30 -0
- package/BULDING.md +2 -1
- package/CMakeLists.txt +7 -2
- package/dist/cjs/lib/index.cjs +4 -1
- package/dist/cjs/lib/index.cjs.map +1 -1
- package/dist/cjs/polyfill/Events.cjs.map +1 -1
- package/dist/cjs/polyfill/RTCDataChannel.cjs +18 -5
- package/dist/cjs/polyfill/RTCDataChannel.cjs.map +1 -1
- package/dist/cjs/polyfill/RTCDtlsTransport.cjs.map +1 -1
- package/dist/cjs/polyfill/RTCPeerConnection.cjs +6 -1
- package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
- package/dist/cjs/polyfill/RTCSctpTransport.cjs.map +1 -1
- package/dist/esm/lib/index.mjs +4 -2
- package/dist/esm/lib/index.mjs.map +1 -1
- package/dist/esm/polyfill/Events.mjs.map +1 -1
- package/dist/esm/polyfill/RTCDataChannel.mjs +18 -5
- package/dist/esm/polyfill/RTCDataChannel.mjs.map +1 -1
- package/dist/esm/polyfill/RTCDtlsTransport.mjs.map +1 -1
- package/dist/esm/polyfill/RTCPeerConnection.mjs +6 -1
- package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
- package/dist/esm/polyfill/RTCSctpTransport.mjs.map +1 -1
- package/dist/types/lib/index.d.ts +14 -3
- package/dist/types/lib/types.d.ts +24 -1
- package/dist/types/polyfill/RTCPeerConnection.d.ts +1 -2
- package/package.json +4 -2
- package/src/cpp/data-channel-wrapper.cpp +432 -411
- package/src/cpp/data-channel-wrapper.h +0 -2
- package/src/cpp/ice-udp-mux-listener-wrapper.cpp +157 -0
- package/src/cpp/ice-udp-mux-listener-wrapper.h +43 -0
- package/src/cpp/main.cpp +12 -10
- package/src/cpp/media-audio-wrapper.cpp +291 -294
- package/src/cpp/media-audio-wrapper.h +1 -3
- package/src/cpp/media-direction.cpp +32 -32
- package/src/cpp/media-direction.h +1 -1
- package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +24 -28
- package/src/cpp/media-rtcpreceivingsession-wrapper.h +0 -5
- package/src/cpp/media-track-wrapper.cpp +350 -339
- package/src/cpp/media-track-wrapper.h +0 -3
- package/src/cpp/media-video-wrapper.cpp +312 -313
- package/src/cpp/media-video-wrapper.h +1 -3
- package/src/cpp/peer-connection-wrapper.cpp +1097 -984
- package/src/cpp/peer-connection-wrapper.h +1 -2
- package/src/cpp/rtc-wrapper.cpp +142 -138
- package/src/cpp/rtc-wrapper.h +8 -10
- package/src/cpp/thread-safe-callback.cpp +39 -50
- package/src/cpp/thread-safe-callback.h +26 -28
- package/src/cpp/web-socket-server-wrapper.cpp +205 -199
- package/src/cpp/web-socket-server-wrapper.h +0 -4
- package/src/cpp/web-socket-wrapper.cpp +625 -598
- package/src/cpp/web-socket-wrapper.h +0 -3
- package/src/lib/index.ts +14 -1
- package/src/lib/types.ts +26 -0
- package/src/polyfill/Events.ts +4 -1
- package/src/polyfill/RTCDataChannel.ts +24 -5
- package/src/polyfill/RTCDtlsTransport.ts +1 -1
- package/src/polyfill/RTCPeerConnection.ts +9 -3
- package/src/polyfill/RTCSctpTransport.ts +2 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#include "data-channel-wrapper.h"
|
|
2
|
-
|
|
3
2
|
#include "plog/Log.h"
|
|
4
3
|
|
|
5
4
|
Napi::FunctionReference DataChannelWrapper::constructor = Napi::FunctionReference();
|
|
@@ -7,503 +6,525 @@ std::unordered_set<DataChannelWrapper *> DataChannelWrapper::instances;
|
|
|
7
6
|
|
|
8
7
|
void DataChannelWrapper::CloseAll()
|
|
9
8
|
{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
PLOG_DEBUG << "CloseAll() called";
|
|
10
|
+
auto copy(instances);
|
|
11
|
+
for (auto inst : copy)
|
|
12
|
+
inst->doClose();
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
void DataChannelWrapper::CleanupAll()
|
|
17
16
|
{
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
PLOG_DEBUG << "CleanupAll() called";
|
|
18
|
+
auto copy(instances);
|
|
19
|
+
for (auto inst : copy)
|
|
20
|
+
inst->doCleanup();
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
25
24
|
{
|
|
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
|
-
return exports;
|
|
25
|
+
Napi::HandleScope scope(env);
|
|
26
|
+
|
|
27
|
+
Napi::Function func = DefineClass(
|
|
28
|
+
env, "DataChannel",
|
|
29
|
+
{
|
|
30
|
+
InstanceMethod("close", &DataChannelWrapper::close),
|
|
31
|
+
InstanceMethod("getLabel", &DataChannelWrapper::getLabel),
|
|
32
|
+
InstanceMethod("getId", &DataChannelWrapper::getId),
|
|
33
|
+
InstanceMethod("getProtocol", &DataChannelWrapper::getProtocol),
|
|
34
|
+
InstanceMethod("sendMessage", &DataChannelWrapper::sendMessage),
|
|
35
|
+
InstanceMethod("sendMessageBinary", &DataChannelWrapper::sendMessageBinary),
|
|
36
|
+
InstanceMethod("isOpen", &DataChannelWrapper::isOpen),
|
|
37
|
+
InstanceMethod("bufferedAmount", &DataChannelWrapper::bufferedAmount),
|
|
38
|
+
InstanceMethod("maxMessageSize", &DataChannelWrapper::maxMessageSize),
|
|
39
|
+
InstanceMethod("setBufferedAmountLowThreshold", &DataChannelWrapper::setBufferedAmountLowThreshold),
|
|
40
|
+
InstanceMethod("onOpen", &DataChannelWrapper::onOpen),
|
|
41
|
+
InstanceMethod("onClosed", &DataChannelWrapper::onClosed),
|
|
42
|
+
InstanceMethod("onError", &DataChannelWrapper::onError),
|
|
43
|
+
InstanceMethod("onBufferedAmountLow", &DataChannelWrapper::onBufferedAmountLow),
|
|
44
|
+
InstanceMethod("onMessage", &DataChannelWrapper::onMessage),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
|
|
48
|
+
if (constructor.IsEmpty())
|
|
49
|
+
{
|
|
50
|
+
constructor = Napi::Persistent(func);
|
|
51
|
+
constructor.SuppressDestruct();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports.Set("DataChannel", func);
|
|
55
|
+
return exports;
|
|
58
56
|
}
|
|
59
57
|
|
|
60
58
|
DataChannelWrapper::DataChannelWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<DataChannelWrapper>(info)
|
|
61
59
|
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
PLOG_DEBUG << "Constructor called";
|
|
61
|
+
mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
|
|
62
|
+
PLOG_DEBUG << "Data Channel created";
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
// Closed callback must be set to trigger cleanup
|
|
65
|
+
mOnClosedCallback =
|
|
66
|
+
std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
|
|
68
67
|
|
|
69
|
-
|
|
68
|
+
instances.insert(this);
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
DataChannelWrapper::~DataChannelWrapper()
|
|
73
72
|
{
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
PLOG_DEBUG << "Destructor called";
|
|
74
|
+
doClose();
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
void DataChannelWrapper::doClose()
|
|
79
78
|
{
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
PLOG_DEBUG << "doClose() called";
|
|
80
|
+
if (mDataChannelPtr)
|
|
81
|
+
{
|
|
82
|
+
PLOG_DEBUG << "Closing...";
|
|
83
|
+
try
|
|
82
84
|
{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
{
|
|
91
|
-
std::cerr << std::string("libdatachannel error while closing data channel: ") + ex.what() << std::endl;
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
85
|
+
mDataChannelPtr->close();
|
|
86
|
+
mDataChannelPtr.reset();
|
|
87
|
+
}
|
|
88
|
+
catch (std::exception &ex)
|
|
89
|
+
{
|
|
90
|
+
std::cerr << std::string("libdatachannel error while closing data channel: ") + ex.what() << std::endl;
|
|
91
|
+
return;
|
|
94
92
|
}
|
|
93
|
+
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
95
|
+
mOnOpenCallback.reset();
|
|
96
|
+
mOnErrorCallback.reset();
|
|
97
|
+
mOnBufferedAmountLowCallback.reset();
|
|
98
|
+
mOnMessageCallback.reset();
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
void DataChannelWrapper::doCleanup()
|
|
103
102
|
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
103
|
+
PLOG_DEBUG << "doCleanup() called";
|
|
104
|
+
mOnClosedCallback.reset();
|
|
105
|
+
|
|
106
|
+
// For close there are 3 cases:
|
|
107
|
+
// 1. Close was called from JS
|
|
108
|
+
// 2. Close was called from RTC
|
|
109
|
+
// 3. Close was not called from JS or RTC (we are destroying the object)
|
|
110
|
+
// This could be coming from rtc (case 2)
|
|
111
|
+
mDataChannelPtr.reset();
|
|
112
|
+
mOnOpenCallback.reset();
|
|
113
|
+
mOnErrorCallback.reset();
|
|
114
|
+
mOnBufferedAmountLowCallback.reset();
|
|
115
|
+
mOnMessageCallback.reset();
|
|
116
|
+
instances.erase(this);
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
void DataChannelWrapper::close(const Napi::CallbackInfo &info)
|
|
121
120
|
{
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
PLOG_DEBUG << "close() called";
|
|
122
|
+
doClose();
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
Napi::Value DataChannelWrapper::getLabel(const Napi::CallbackInfo &info)
|
|
127
126
|
{
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
PLOG_DEBUG << "getLabel() called";
|
|
128
|
+
if (!mDataChannelPtr)
|
|
129
|
+
{
|
|
130
|
+
Napi::Error::New(info.Env(), "getLabel() called on destroyed channel").ThrowAsJavaScriptException();
|
|
131
|
+
return info.Env().Null();
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Napi::String::New(info.Env(), mDataChannelPtr->label());
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
Napi::Value DataChannelWrapper::getId(const Napi::CallbackInfo &info)
|
|
139
138
|
{
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
PLOG_DEBUG << "getId() called";
|
|
140
|
+
if (!mDataChannelPtr)
|
|
141
|
+
{
|
|
142
|
+
Napi::Error::New(info.Env(), "getId() called on destroyed channel").ThrowAsJavaScriptException();
|
|
143
|
+
return info.Env().Null();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return Napi::Number::New(info.Env(), mDataChannelPtr->id().value_or(-1));
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
Napi::Value DataChannelWrapper::getProtocol(const Napi::CallbackInfo &info)
|
|
151
150
|
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
151
|
+
PLOG_DEBUG << "getProtocol() called";
|
|
152
|
+
if (!mDataChannelPtr)
|
|
153
|
+
{
|
|
154
|
+
Napi::Error::New(info.Env(), "getProtocol() called on destroyed channel").ThrowAsJavaScriptException();
|
|
155
|
+
return info.Env().Null();
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return Napi::String::New(info.Env(), mDataChannelPtr->protocol());
|
|
160
159
|
}
|
|
161
160
|
|
|
162
161
|
Napi::Value DataChannelWrapper::sendMessage(const Napi::CallbackInfo &info)
|
|
163
162
|
{
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
163
|
+
PLOG_DEBUG << "sendMessage() called";
|
|
164
|
+
if (!mDataChannelPtr)
|
|
165
|
+
{
|
|
166
|
+
Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
|
|
167
|
+
return info.Env().Null();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
Napi::Env env = info.Env();
|
|
171
|
+
int length = info.Length();
|
|
172
|
+
|
|
173
|
+
// Allow call with NULL
|
|
174
|
+
if (length < 1 || (!info[0].IsString() && !info[0].IsNull()))
|
|
175
|
+
{
|
|
176
|
+
Napi::TypeError::New(env, "String or Null expected").ThrowAsJavaScriptException();
|
|
177
|
+
return info.Env().Null();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
try
|
|
181
|
+
{
|
|
182
|
+
return Napi::Boolean::New(info.Env(), mDataChannelPtr->send(info[0].As<Napi::String>().ToString()));
|
|
183
|
+
}
|
|
184
|
+
catch (std::exception &ex)
|
|
185
|
+
{
|
|
186
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
|
|
187
|
+
.ThrowAsJavaScriptException();
|
|
188
|
+
return Napi::Boolean::New(info.Env(), false);
|
|
189
|
+
}
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
Napi::Value DataChannelWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
|
|
193
193
|
{
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
194
|
+
PLOG_DEBUG << "sendMessageBinary() called";
|
|
195
|
+
if (!mDataChannelPtr)
|
|
196
|
+
{
|
|
197
|
+
Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
|
|
198
|
+
return info.Env().Null();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Napi::Env env = info.Env();
|
|
202
|
+
int length = info.Length();
|
|
203
|
+
|
|
204
|
+
if (length < 1 || !info[0].IsBuffer())
|
|
205
|
+
{
|
|
206
|
+
Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
|
|
207
|
+
return info.Env().Null();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try
|
|
211
|
+
{
|
|
212
|
+
Napi::Uint8Array buffer = info[0].As<Napi::Uint8Array>();
|
|
213
|
+
return Napi::Boolean::New(info.Env(), mDataChannelPtr->send((std::byte *)buffer.Data(), buffer.ByteLength()));
|
|
214
|
+
}
|
|
215
|
+
catch (std::exception &ex)
|
|
216
|
+
{
|
|
217
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
|
|
218
|
+
.ThrowAsJavaScriptException();
|
|
219
|
+
return Napi::Boolean::New(info.Env(), false);
|
|
220
|
+
}
|
|
220
221
|
}
|
|
221
222
|
|
|
222
223
|
Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
|
|
223
224
|
{
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
225
|
+
PLOG_DEBUG << "isOpen() called";
|
|
226
|
+
Napi::Env env = info.Env();
|
|
227
|
+
|
|
228
|
+
if (!mDataChannelPtr)
|
|
229
|
+
{
|
|
230
|
+
return Napi::Boolean::New(info.Env(), false);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
try
|
|
234
|
+
{
|
|
235
|
+
return Napi::Boolean::New(info.Env(), mDataChannelPtr->isOpen());
|
|
236
|
+
}
|
|
237
|
+
catch (std::exception &ex)
|
|
238
|
+
{
|
|
239
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
240
|
+
return Napi::Boolean::New(info.Env(), false);
|
|
241
|
+
}
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
|
|
244
245
|
{
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
246
|
+
PLOG_DEBUG << "bufferedAmount() called";
|
|
247
|
+
Napi::Env env = info.Env();
|
|
248
|
+
|
|
249
|
+
if (!mDataChannelPtr)
|
|
250
|
+
{
|
|
251
|
+
return Napi::Number::New(info.Env(), 0);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
try
|
|
255
|
+
{
|
|
256
|
+
return Napi::Number::New(info.Env(), mDataChannelPtr->bufferedAmount());
|
|
257
|
+
}
|
|
258
|
+
catch (std::exception &ex)
|
|
259
|
+
{
|
|
260
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
261
|
+
return Napi::Number::New(info.Env(), 0);
|
|
262
|
+
}
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
Napi::Value DataChannelWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
265
266
|
{
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
267
|
+
PLOG_DEBUG << "maxMessageSize() called";
|
|
268
|
+
Napi::Env env = info.Env();
|
|
269
|
+
|
|
270
|
+
if (!mDataChannelPtr)
|
|
271
|
+
{
|
|
272
|
+
return Napi::Number::New(info.Env(), 0);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
try
|
|
276
|
+
{
|
|
277
|
+
return Napi::Number::New(info.Env(), mDataChannelPtr->maxMessageSize());
|
|
278
|
+
}
|
|
279
|
+
catch (std::exception &ex)
|
|
280
|
+
{
|
|
281
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
282
|
+
return Napi::Number::New(info.Env(), 0);
|
|
283
|
+
}
|
|
283
284
|
}
|
|
284
285
|
|
|
285
286
|
void DataChannelWrapper::setBufferedAmountLowThreshold(const Napi::CallbackInfo &info)
|
|
286
287
|
{
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
288
|
+
PLOG_DEBUG << "setBufferedAmountLowThreshold() called";
|
|
289
|
+
if (!mDataChannelPtr)
|
|
290
|
+
{
|
|
291
|
+
Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel")
|
|
292
|
+
.ThrowAsJavaScriptException();
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
Napi::Env env = info.Env();
|
|
297
|
+
int length = info.Length();
|
|
298
|
+
|
|
299
|
+
if (length < 1 || !info[0].IsNumber())
|
|
300
|
+
{
|
|
301
|
+
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
try
|
|
306
|
+
{
|
|
307
|
+
mDataChannelPtr->setBufferedAmountLowThreshold(info[0].ToNumber().Uint32Value());
|
|
308
|
+
}
|
|
309
|
+
catch (std::exception &ex)
|
|
310
|
+
{
|
|
311
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
312
314
|
}
|
|
313
315
|
|
|
314
316
|
void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
315
317
|
{
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
318
|
+
PLOG_DEBUG << "onOpen() called";
|
|
319
|
+
if (!mDataChannelPtr)
|
|
320
|
+
{
|
|
321
|
+
Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
Napi::Env env = info.Env();
|
|
326
|
+
int length = info.Length();
|
|
327
|
+
|
|
328
|
+
if (length < 1 || !info[0].IsFunction())
|
|
329
|
+
{
|
|
330
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Callback
|
|
335
|
+
mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
336
|
+
|
|
337
|
+
mDataChannelPtr->onOpen(
|
|
338
|
+
[&]()
|
|
339
|
+
{
|
|
340
|
+
PLOG_DEBUG << "onOpen cb received from rtc";
|
|
341
|
+
if (mOnOpenCallback)
|
|
342
|
+
mOnOpenCallback->call(
|
|
343
|
+
[this](Napi::Env env, std::vector<napi_value> &args)
|
|
344
|
+
{
|
|
345
|
+
PLOG_DEBUG << "mOnOpenCallback call(1)";
|
|
346
|
+
// Check the data channel is not closed
|
|
347
|
+
if (instances.find(this) == instances.end())
|
|
348
|
+
throw ThreadSafeCallback::CancelException();
|
|
349
|
+
|
|
350
|
+
// This will run in main thread and needs to construct the
|
|
351
|
+
// arguments for the call
|
|
352
|
+
args = {};
|
|
353
|
+
PLOG_DEBUG << "mOnOpenCallback call(2)";
|
|
354
|
+
});
|
|
355
|
+
});
|
|
350
356
|
}
|
|
351
357
|
|
|
352
358
|
void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
|
|
353
359
|
{
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
360
|
+
PLOG_DEBUG << "onClosed() called";
|
|
361
|
+
if (!mDataChannelPtr)
|
|
362
|
+
{
|
|
363
|
+
Napi::Error::New(info.Env(), "onClosed() called on destroyed channel").ThrowAsJavaScriptException();
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
Napi::Env env = info.Env();
|
|
368
|
+
int length = info.Length();
|
|
369
|
+
|
|
370
|
+
if (length < 1 || !info[0].IsFunction())
|
|
371
|
+
{
|
|
372
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
// Callback
|
|
377
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
378
|
+
|
|
379
|
+
mDataChannelPtr->onClosed(
|
|
380
|
+
[&]()
|
|
381
|
+
{
|
|
382
|
+
PLOG_DEBUG << "onClosed cb received from rtc";
|
|
383
|
+
if (mOnClosedCallback)
|
|
384
|
+
mOnClosedCallback->call(
|
|
385
|
+
[this](Napi::Env env, std::vector<napi_value> &args)
|
|
386
|
+
{
|
|
387
|
+
PLOG_DEBUG << "mOnClosedCallback call";
|
|
388
|
+
// Do not check if the data channel has been closed here
|
|
389
|
+
|
|
390
|
+
// This will run in main thread and needs to construct the
|
|
391
|
+
// arguments for the call
|
|
392
|
+
args = {};
|
|
393
|
+
},
|
|
394
|
+
[this] { doCleanup(); });
|
|
395
|
+
});
|
|
387
396
|
}
|
|
388
397
|
|
|
389
398
|
void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
|
|
390
399
|
{
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
400
|
+
PLOG_DEBUG << "onError() called";
|
|
401
|
+
if (!mDataChannelPtr)
|
|
402
|
+
{
|
|
403
|
+
Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
Napi::Env env = info.Env();
|
|
408
|
+
int length = info.Length();
|
|
409
|
+
|
|
410
|
+
if (length < 1 || !info[0].IsFunction())
|
|
411
|
+
{
|
|
412
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Callback
|
|
417
|
+
mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
418
|
+
|
|
419
|
+
mDataChannelPtr->onError(
|
|
420
|
+
[&](std::string error)
|
|
421
|
+
{
|
|
422
|
+
PLOG_DEBUG << "onError cb received from rtc";
|
|
423
|
+
if (mOnErrorCallback)
|
|
424
|
+
mOnErrorCallback->call(
|
|
425
|
+
[this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args)
|
|
426
|
+
{
|
|
427
|
+
PLOG_DEBUG << "mOnErrorCallback call(1)";
|
|
428
|
+
// Check the data channel is not closed
|
|
429
|
+
if (instances.find(this) == instances.end())
|
|
430
|
+
throw ThreadSafeCallback::CancelException();
|
|
431
|
+
|
|
432
|
+
// This will run in main thread and needs to construct the
|
|
433
|
+
// arguments for the call
|
|
434
|
+
args = {Napi::String::New(env, error)};
|
|
435
|
+
PLOG_DEBUG << "mOnErrorCallback call(2)";
|
|
436
|
+
});
|
|
437
|
+
});
|
|
425
438
|
}
|
|
426
439
|
|
|
427
440
|
void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
|
|
428
441
|
{
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
442
|
+
PLOG_DEBUG << "onBufferedAmountLow() called";
|
|
443
|
+
if (!mDataChannelPtr)
|
|
444
|
+
{
|
|
445
|
+
Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
Napi::Env env = info.Env();
|
|
450
|
+
int length = info.Length();
|
|
451
|
+
|
|
452
|
+
if (length < 1 || !info[0].IsFunction())
|
|
453
|
+
{
|
|
454
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Callback
|
|
459
|
+
mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
460
|
+
|
|
461
|
+
mDataChannelPtr->onBufferedAmountLow(
|
|
462
|
+
[&]()
|
|
463
|
+
{
|
|
464
|
+
PLOG_DEBUG << "onBufferedAmountLow cb received from rtc";
|
|
465
|
+
if (mOnBufferedAmountLowCallback)
|
|
466
|
+
mOnBufferedAmountLowCallback->call(
|
|
467
|
+
[this](Napi::Env env, std::vector<napi_value> &args)
|
|
468
|
+
{
|
|
469
|
+
PLOG_DEBUG << "mOnBufferedAmountLowCallback call(1)";
|
|
470
|
+
// Check the data channel is not closed
|
|
471
|
+
if (instances.find(this) == instances.end())
|
|
472
|
+
throw ThreadSafeCallback::CancelException();
|
|
473
|
+
|
|
474
|
+
// This will run in main thread and needs to construct the
|
|
475
|
+
// arguments for the call
|
|
476
|
+
args = {};
|
|
477
|
+
PLOG_DEBUG << "mOnBufferedAmountLowCallback call(2)";
|
|
478
|
+
});
|
|
479
|
+
});
|
|
463
480
|
}
|
|
464
481
|
|
|
465
482
|
void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
|
|
466
483
|
{
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
484
|
+
PLOG_DEBUG << "onMessage() called";
|
|
485
|
+
if (!mDataChannelPtr)
|
|
486
|
+
{
|
|
487
|
+
Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
Napi::Env env = info.Env();
|
|
492
|
+
int length = info.Length();
|
|
493
|
+
|
|
494
|
+
if (length < 1 || !info[0].IsFunction())
|
|
495
|
+
{
|
|
496
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Callback
|
|
501
|
+
mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
502
|
+
|
|
503
|
+
mDataChannelPtr->onMessage(
|
|
504
|
+
[&](std::variant<rtc::binary, std::string> message)
|
|
505
|
+
{
|
|
506
|
+
PLOG_DEBUG << "onMessage cb received from rtc";
|
|
507
|
+
if (mOnMessageCallback)
|
|
508
|
+
mOnMessageCallback->call(
|
|
509
|
+
[this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args)
|
|
510
|
+
{
|
|
511
|
+
PLOG_DEBUG << "mOnMessageCallback call(1)";
|
|
512
|
+
// Check the data channel is not closed
|
|
513
|
+
if (instances.find(this) == instances.end())
|
|
514
|
+
throw ThreadSafeCallback::CancelException();
|
|
515
|
+
|
|
516
|
+
// This will run in main thread and needs to construct the
|
|
517
|
+
// arguments for the call
|
|
518
|
+
if (std::holds_alternative<std::string>(message))
|
|
519
|
+
{
|
|
520
|
+
args = {Napi::String::New(env, std::get<std::string>(message))};
|
|
521
|
+
}
|
|
522
|
+
else
|
|
523
|
+
{
|
|
524
|
+
auto bin = std::get<rtc::binary>(std::move(message));
|
|
525
|
+
args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
|
|
526
|
+
}
|
|
527
|
+
PLOG_DEBUG << "mOnMessageCallback call(2)";
|
|
528
|
+
});
|
|
529
|
+
});
|
|
509
530
|
}
|