node-datachannel 0.3.0 → 0.3.3
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/.github/workflows/build-linux.yml +1 -1
- package/.github/workflows/build-mac.yml +1 -1
- package/.github/workflows/build-win.yml +1 -1
- package/.github/workflows/lint.yml +19 -0
- package/CMakeLists.txt +3 -3
- package/README.md +2 -0
- package/examples/client-server/client-benchmark.js +43 -32
- package/examples/client-server/client-periodic.js +30 -14
- package/examples/client-server/client.js +6 -5
- package/examples/client-server/package-lock.json +183 -44
- package/examples/client-server/signaling-server.js +3 -5
- package/examples/media/media.js +9 -9
- package/lib/index.d.ts +102 -101
- package/node_modules/lru-cache/package.json +2 -4
- package/node_modules/minimist/package.json +0 -1
- package/node_modules/node-abi/node_modules/semver/README.md +3 -1
- package/node_modules/node-abi/node_modules/semver/bin/semver.js +19 -9
- package/node_modules/node-abi/node_modules/semver/classes/comparator.js +3 -2
- package/node_modules/node-abi/node_modules/semver/classes/index.js +1 -1
- package/node_modules/node-abi/node_modules/semver/classes/range.js +31 -22
- package/node_modules/node-abi/node_modules/semver/classes/semver.js +1 -1
- package/node_modules/node-abi/node_modules/semver/functions/cmp.js +8 -4
- package/node_modules/node-abi/node_modules/semver/functions/coerce.js +3 -2
- package/node_modules/node-abi/node_modules/semver/functions/inc.js +4 -1
- package/node_modules/node-abi/node_modules/semver/functions/parse.js +1 -1
- package/node_modules/node-abi/node_modules/semver/internal/constants.js +2 -2
- package/node_modules/node-abi/node_modules/semver/internal/identifiers.js +1 -1
- package/node_modules/node-abi/node_modules/semver/internal/parse-options.js +3 -3
- package/node_modules/node-abi/node_modules/semver/internal/re.js +3 -3
- package/node_modules/node-abi/node_modules/semver/package.json +51 -18
- package/node_modules/node-abi/node_modules/semver/ranges/min-version.js +2 -1
- package/node_modules/node-abi/node_modules/semver/ranges/outside.js +1 -1
- package/node_modules/node-abi/node_modules/semver/ranges/simplify.js +15 -12
- package/node_modules/node-abi/node_modules/semver/ranges/subset.js +53 -31
- package/node_modules/npmlog/node_modules/are-we-there-yet/package.json +10 -10
- package/node_modules/npmlog/package.json +1 -1
- package/node_modules/tar-stream/node_modules/bl/.travis.yml +4 -3
- package/node_modules/tar-stream/node_modules/bl/BufferList.js +1 -1
- package/node_modules/tar-stream/node_modules/bl/package.json +10 -10
- package/node_modules/tar-stream/node_modules/bl/test/test.js +20 -2
- package/node_modules/wide-align/LICENSE +0 -0
- package/node_modules/wide-align/README.md +0 -0
- package/node_modules/wide-align/align.js +0 -0
- package/node_modules/wide-align/package.json +14 -14
- package/package.json +2 -2
- package/src/data-channel-wrapper.cpp +69 -53
- package/src/data-channel-wrapper.h +0 -1
- package/src/media-track-wrapper.cpp +91 -52
- package/src/media-track-wrapper.h +0 -1
- package/src/peer-connection-wrapper.cpp +111 -71
- package/src/peer-connection-wrapper.h +0 -2
- package/test/connectivity.js +18 -17
- package/test/test.js +22 -30
- package/node_modules/node-abi/node_modules/semver/CHANGELOG.md +0 -111
|
@@ -44,26 +44,8 @@ Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
44
44
|
|
|
45
45
|
DataChannelWrapper::DataChannelWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<DataChannelWrapper>(info)
|
|
46
46
|
{
|
|
47
|
-
mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
|
|
47
|
+
mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
|
|
48
48
|
|
|
49
|
-
mDataChannelPtr->onClosed([&]()
|
|
50
|
-
{
|
|
51
|
-
if (mOnClosedCallback)
|
|
52
|
-
mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
53
|
-
// Check the peer connection is not closed
|
|
54
|
-
if(instances.find(this) == instances.end())
|
|
55
|
-
throw ThreadSafeCallback::CancelException();
|
|
56
|
-
|
|
57
|
-
cleanCbsAndEraseInstance();
|
|
58
|
-
|
|
59
|
-
// This will run in main thread and needs to construct the
|
|
60
|
-
// arguments for the call
|
|
61
|
-
args = {};
|
|
62
|
-
});
|
|
63
|
-
else {
|
|
64
|
-
cleanCbsAndEraseInstance();
|
|
65
|
-
} });
|
|
66
|
-
|
|
67
49
|
instances.insert(this);
|
|
68
50
|
}
|
|
69
51
|
|
|
@@ -79,17 +61,15 @@ void DataChannelWrapper::doClose()
|
|
|
79
61
|
try
|
|
80
62
|
{
|
|
81
63
|
mDataChannelPtr->close();
|
|
64
|
+
mDataChannelPtr.reset();
|
|
82
65
|
}
|
|
83
66
|
catch (std::exception &ex)
|
|
84
67
|
{
|
|
85
|
-
std::
|
|
68
|
+
std::cerr << std::string("libdatachannel error while closing data channel: ") + ex.what() << std::endl;
|
|
86
69
|
return;
|
|
87
70
|
}
|
|
88
71
|
}
|
|
89
|
-
}
|
|
90
72
|
|
|
91
|
-
void DataChannelWrapper::cleanCbsAndEraseInstance()
|
|
92
|
-
{
|
|
93
73
|
mOnOpenCallback.reset();
|
|
94
74
|
mOnClosedCallback.reset();
|
|
95
75
|
mOnErrorCallback.reset();
|
|
@@ -97,7 +77,6 @@ void DataChannelWrapper::cleanCbsAndEraseInstance()
|
|
|
97
77
|
mOnMessageCallback.reset();
|
|
98
78
|
|
|
99
79
|
instances.erase(this);
|
|
100
|
-
mDataChannelPtr.reset();
|
|
101
80
|
}
|
|
102
81
|
|
|
103
82
|
void DataChannelWrapper::close(const Napi::CallbackInfo &info)
|
|
@@ -109,7 +88,7 @@ Napi::Value DataChannelWrapper::getLabel(const Napi::CallbackInfo &info)
|
|
|
109
88
|
{
|
|
110
89
|
if (!mDataChannelPtr)
|
|
111
90
|
{
|
|
112
|
-
Napi::Error::New(info.Env(), "
|
|
91
|
+
Napi::Error::New(info.Env(), "getLabel() called on destroyed channel").ThrowAsJavaScriptException();
|
|
113
92
|
return info.Env().Null();
|
|
114
93
|
}
|
|
115
94
|
|
|
@@ -120,7 +99,7 @@ Napi::Value DataChannelWrapper::getId(const Napi::CallbackInfo &info)
|
|
|
120
99
|
{
|
|
121
100
|
if (!mDataChannelPtr)
|
|
122
101
|
{
|
|
123
|
-
Napi::Error::New(info.Env(), "
|
|
102
|
+
Napi::Error::New(info.Env(), "getId() called on destroyed channel").ThrowAsJavaScriptException();
|
|
124
103
|
return info.Env().Null();
|
|
125
104
|
}
|
|
126
105
|
|
|
@@ -131,7 +110,7 @@ Napi::Value DataChannelWrapper::getProtocol(const Napi::CallbackInfo &info)
|
|
|
131
110
|
{
|
|
132
111
|
if (!mDataChannelPtr)
|
|
133
112
|
{
|
|
134
|
-
Napi::Error::New(info.Env(), "
|
|
113
|
+
Napi::Error::New(info.Env(), "getProtocol() called on destroyed channel").ThrowAsJavaScriptException();
|
|
135
114
|
return info.Env().Null();
|
|
136
115
|
}
|
|
137
116
|
|
|
@@ -142,7 +121,7 @@ Napi::Value DataChannelWrapper::sendMessage(const Napi::CallbackInfo &info)
|
|
|
142
121
|
{
|
|
143
122
|
if (!mDataChannelPtr)
|
|
144
123
|
{
|
|
145
|
-
Napi::Error::New(info.Env(), "
|
|
124
|
+
Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
|
|
146
125
|
return info.Env().Null();
|
|
147
126
|
}
|
|
148
127
|
|
|
@@ -162,7 +141,7 @@ Napi::Value DataChannelWrapper::sendMessage(const Napi::CallbackInfo &info)
|
|
|
162
141
|
}
|
|
163
142
|
catch (std::exception &ex)
|
|
164
143
|
{
|
|
165
|
-
Napi::Error::New(env, std::string("libdatachannel error while sending
|
|
144
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
|
|
166
145
|
return Napi::Boolean::New(info.Env(), false);
|
|
167
146
|
}
|
|
168
147
|
}
|
|
@@ -171,7 +150,7 @@ Napi::Value DataChannelWrapper::sendMessageBinary(const Napi::CallbackInfo &info
|
|
|
171
150
|
{
|
|
172
151
|
if (!mDataChannelPtr)
|
|
173
152
|
{
|
|
174
|
-
Napi::Error::New(info.Env(), "
|
|
153
|
+
Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
|
|
175
154
|
return info.Env().Null();
|
|
176
155
|
}
|
|
177
156
|
|
|
@@ -191,7 +170,7 @@ Napi::Value DataChannelWrapper::sendMessageBinary(const Napi::CallbackInfo &info
|
|
|
191
170
|
}
|
|
192
171
|
catch (std::exception &ex)
|
|
193
172
|
{
|
|
194
|
-
Napi::Error::New(env, std::string("libdatachannel error while sending
|
|
173
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
|
|
195
174
|
return Napi::Boolean::New(info.Env(), false);
|
|
196
175
|
}
|
|
197
176
|
}
|
|
@@ -199,6 +178,7 @@ Napi::Value DataChannelWrapper::sendMessageBinary(const Napi::CallbackInfo &info
|
|
|
199
178
|
Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
|
|
200
179
|
{
|
|
201
180
|
Napi::Env env = info.Env();
|
|
181
|
+
|
|
202
182
|
if (!mDataChannelPtr)
|
|
203
183
|
{
|
|
204
184
|
return Napi::Boolean::New(info.Env(), false);
|
|
@@ -210,7 +190,7 @@ Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
|
|
|
210
190
|
}
|
|
211
191
|
catch (std::exception &ex)
|
|
212
192
|
{
|
|
213
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
193
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
214
194
|
return Napi::Boolean::New(info.Env(), false);
|
|
215
195
|
}
|
|
216
196
|
}
|
|
@@ -218,6 +198,7 @@ Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
|
|
|
218
198
|
Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
|
|
219
199
|
{
|
|
220
200
|
Napi::Env env = info.Env();
|
|
201
|
+
|
|
221
202
|
if (!mDataChannelPtr)
|
|
222
203
|
{
|
|
223
204
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -229,7 +210,7 @@ Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
|
|
|
229
210
|
}
|
|
230
211
|
catch (std::exception &ex)
|
|
231
212
|
{
|
|
232
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
213
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
233
214
|
return Napi::Number::New(info.Env(), 0);
|
|
234
215
|
}
|
|
235
216
|
}
|
|
@@ -237,6 +218,7 @@ Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
|
|
|
237
218
|
Napi::Value DataChannelWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
238
219
|
{
|
|
239
220
|
Napi::Env env = info.Env();
|
|
221
|
+
|
|
240
222
|
if (!mDataChannelPtr)
|
|
241
223
|
{
|
|
242
224
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -248,7 +230,7 @@ Napi::Value DataChannelWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
|
248
230
|
}
|
|
249
231
|
catch (std::exception &ex)
|
|
250
232
|
{
|
|
251
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
233
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
252
234
|
return Napi::Number::New(info.Env(), 0);
|
|
253
235
|
}
|
|
254
236
|
}
|
|
@@ -257,7 +239,7 @@ void DataChannelWrapper::setBufferedAmountLowThreshold(const Napi::CallbackInfo
|
|
|
257
239
|
{
|
|
258
240
|
if (!mDataChannelPtr)
|
|
259
241
|
{
|
|
260
|
-
Napi::Error::New(info.Env(), "
|
|
242
|
+
Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel").ThrowAsJavaScriptException();
|
|
261
243
|
return;
|
|
262
244
|
}
|
|
263
245
|
|
|
@@ -276,13 +258,19 @@ void DataChannelWrapper::setBufferedAmountLowThreshold(const Napi::CallbackInfo
|
|
|
276
258
|
}
|
|
277
259
|
catch (std::exception &ex)
|
|
278
260
|
{
|
|
279
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
261
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
280
262
|
return;
|
|
281
263
|
}
|
|
282
264
|
}
|
|
283
265
|
|
|
284
266
|
void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
285
267
|
{
|
|
268
|
+
if (!mDataChannelPtr)
|
|
269
|
+
{
|
|
270
|
+
Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
286
274
|
Napi::Env env = info.Env();
|
|
287
275
|
int length = info.Length();
|
|
288
276
|
|
|
@@ -295,11 +283,10 @@ void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
|
295
283
|
// Callback
|
|
296
284
|
mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
297
285
|
|
|
298
|
-
mDataChannelPtr->onOpen([&]()
|
|
299
|
-
{
|
|
286
|
+
mDataChannelPtr->onOpen([&]() {
|
|
300
287
|
if (mOnOpenCallback)
|
|
301
288
|
mOnOpenCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
302
|
-
// Check the
|
|
289
|
+
// Check the data channel is not closed
|
|
303
290
|
if(instances.find(this) == instances.end())
|
|
304
291
|
throw ThreadSafeCallback::CancelException();
|
|
305
292
|
|
|
@@ -311,6 +298,12 @@ void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
|
311
298
|
|
|
312
299
|
void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
|
|
313
300
|
{
|
|
301
|
+
if (!mDataChannelPtr)
|
|
302
|
+
{
|
|
303
|
+
Napi::Error::New(info.Env(), "onClosed() called on destroyed channel").ThrowAsJavaScriptException();
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
314
307
|
Napi::Env env = info.Env();
|
|
315
308
|
int length = info.Length();
|
|
316
309
|
|
|
@@ -323,11 +316,25 @@ void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
|
|
|
323
316
|
// Callback
|
|
324
317
|
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
325
318
|
|
|
326
|
-
|
|
319
|
+
mDataChannelPtr->onClosed([&]() {
|
|
320
|
+
if (mOnClosedCallback)
|
|
321
|
+
mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
322
|
+
// Do not check if the data channel has been closed here
|
|
323
|
+
|
|
324
|
+
// This will run in main thread and needs to construct the
|
|
325
|
+
// arguments for the call
|
|
326
|
+
args = {};
|
|
327
|
+
}); });
|
|
327
328
|
}
|
|
328
329
|
|
|
329
330
|
void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
|
|
330
331
|
{
|
|
332
|
+
if (!mDataChannelPtr)
|
|
333
|
+
{
|
|
334
|
+
Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
331
338
|
Napi::Env env = info.Env();
|
|
332
339
|
int length = info.Length();
|
|
333
340
|
|
|
@@ -340,11 +347,10 @@ void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
|
|
|
340
347
|
// Callback
|
|
341
348
|
mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
342
349
|
|
|
343
|
-
mDataChannelPtr->onError([&](
|
|
344
|
-
{
|
|
350
|
+
mDataChannelPtr->onError([&](std::string error) {
|
|
345
351
|
if (mOnErrorCallback)
|
|
346
|
-
mOnErrorCallback->call([this, error](Napi::Env env, std::vector<napi_value> &args) {
|
|
347
|
-
// Check the
|
|
352
|
+
mOnErrorCallback->call([this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args) {
|
|
353
|
+
// Check the data channel is not closed
|
|
348
354
|
if(instances.find(this) == instances.end())
|
|
349
355
|
throw ThreadSafeCallback::CancelException();
|
|
350
356
|
|
|
@@ -356,6 +362,12 @@ void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
|
|
|
356
362
|
|
|
357
363
|
void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
|
|
358
364
|
{
|
|
365
|
+
if (!mDataChannelPtr)
|
|
366
|
+
{
|
|
367
|
+
Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
359
371
|
Napi::Env env = info.Env();
|
|
360
372
|
int length = info.Length();
|
|
361
373
|
|
|
@@ -368,11 +380,10 @@ void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
|
|
|
368
380
|
// Callback
|
|
369
381
|
mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
370
382
|
|
|
371
|
-
mDataChannelPtr->onBufferedAmountLow([&]()
|
|
372
|
-
{
|
|
383
|
+
mDataChannelPtr->onBufferedAmountLow([&]() {
|
|
373
384
|
if (mOnBufferedAmountLowCallback)
|
|
374
385
|
mOnBufferedAmountLowCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
375
|
-
// Check the
|
|
386
|
+
// Check the data channel is not closed
|
|
376
387
|
if(instances.find(this) == instances.end())
|
|
377
388
|
throw ThreadSafeCallback::CancelException();
|
|
378
389
|
|
|
@@ -384,6 +395,12 @@ void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
|
|
|
384
395
|
|
|
385
396
|
void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
|
|
386
397
|
{
|
|
398
|
+
if (!mDataChannelPtr)
|
|
399
|
+
{
|
|
400
|
+
Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
387
404
|
Napi::Env env = info.Env();
|
|
388
405
|
int length = info.Length();
|
|
389
406
|
|
|
@@ -396,24 +413,23 @@ void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
|
|
|
396
413
|
// Callback
|
|
397
414
|
mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
398
415
|
|
|
399
|
-
mDataChannelPtr->onMessage([&](
|
|
400
|
-
{
|
|
416
|
+
mDataChannelPtr->onMessage([&](std::variant<rtc::binary, std::string> message) {
|
|
401
417
|
if (mOnMessageCallback)
|
|
402
|
-
mOnMessageCallback->call([this, message](Napi::Env env, std::vector<napi_value> &args) {
|
|
403
|
-
// Check the
|
|
418
|
+
mOnMessageCallback->call([this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args) {
|
|
419
|
+
// Check the data channel is not closed
|
|
404
420
|
if(instances.find(this) == instances.end())
|
|
405
421
|
throw ThreadSafeCallback::CancelException();
|
|
406
422
|
|
|
407
423
|
// This will run in main thread and needs to construct the
|
|
408
424
|
// arguments for the call
|
|
409
|
-
Napi::Object payload = Napi::Object::New(env);
|
|
410
425
|
if (std::holds_alternative<std::string>(message))
|
|
411
426
|
{
|
|
412
427
|
args = {Napi::String::New(env, std::get<std::string>(message))};
|
|
413
428
|
}
|
|
414
429
|
else
|
|
415
430
|
{
|
|
416
|
-
|
|
431
|
+
auto bin = std::get<rtc::binary>(std::move(message));
|
|
432
|
+
args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
|
|
417
433
|
}
|
|
418
434
|
}); });
|
|
419
435
|
}
|
|
@@ -46,26 +46,8 @@ Napi::Object TrackWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
46
46
|
|
|
47
47
|
TrackWrapper::TrackWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<TrackWrapper>(info)
|
|
48
48
|
{
|
|
49
|
-
mTrackPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::Track>>>().Data());
|
|
49
|
+
mTrackPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::Track>>>().Data());
|
|
50
50
|
|
|
51
|
-
mTrackPtr->onClosed([&]()
|
|
52
|
-
{
|
|
53
|
-
if (mOnClosedCallback)
|
|
54
|
-
mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
55
|
-
// Check the peer connection is not closed
|
|
56
|
-
if(instances.find(this) == instances.end())
|
|
57
|
-
throw ThreadSafeCallback::CancelException();
|
|
58
|
-
|
|
59
|
-
cleanCbsAndEraseInstance();
|
|
60
|
-
|
|
61
|
-
// This will run in main thread and needs to construct the
|
|
62
|
-
// arguments for the call
|
|
63
|
-
args = {};
|
|
64
|
-
});
|
|
65
|
-
else {
|
|
66
|
-
cleanCbsAndEraseInstance();
|
|
67
|
-
} });
|
|
68
|
-
|
|
69
51
|
instances.insert(this);
|
|
70
52
|
}
|
|
71
53
|
|
|
@@ -81,24 +63,21 @@ void TrackWrapper::doClose()
|
|
|
81
63
|
try
|
|
82
64
|
{
|
|
83
65
|
mTrackPtr->close();
|
|
66
|
+
mTrackPtr.reset();
|
|
84
67
|
}
|
|
85
68
|
catch (std::exception &ex)
|
|
86
69
|
{
|
|
87
|
-
std::
|
|
70
|
+
std::cerr << std::string("libdatachannel error while closing track: ") + ex.what() << std::endl;
|
|
88
71
|
return;
|
|
89
72
|
}
|
|
90
73
|
}
|
|
91
|
-
}
|
|
92
74
|
|
|
93
|
-
void TrackWrapper::cleanCbsAndEraseInstance()
|
|
94
|
-
{
|
|
95
75
|
mOnOpenCallback.reset();
|
|
96
76
|
mOnClosedCallback.reset();
|
|
97
77
|
mOnErrorCallback.reset();
|
|
98
78
|
mOnMessageCallback.reset();
|
|
99
79
|
|
|
100
80
|
instances.erase(this);
|
|
101
|
-
mTrackPtr.reset();
|
|
102
81
|
}
|
|
103
82
|
|
|
104
83
|
void TrackWrapper::close(const Napi::CallbackInfo &info)
|
|
@@ -108,18 +87,36 @@ void TrackWrapper::close(const Napi::CallbackInfo &info)
|
|
|
108
87
|
|
|
109
88
|
Napi::Value TrackWrapper::direction(const Napi::CallbackInfo &info)
|
|
110
89
|
{
|
|
90
|
+
if (!mTrackPtr)
|
|
91
|
+
{
|
|
92
|
+
Napi::Error::New(info.Env(), "direction() called on destroyed track").ThrowAsJavaScriptException();
|
|
93
|
+
return info.Env().Null();
|
|
94
|
+
}
|
|
95
|
+
|
|
111
96
|
Napi::Env env = info.Env();
|
|
112
97
|
return Napi::String::New(env, directionToStr(mTrackPtr->direction()));
|
|
113
98
|
}
|
|
114
99
|
|
|
115
100
|
Napi::Value TrackWrapper::mid(const Napi::CallbackInfo &info)
|
|
116
101
|
{
|
|
102
|
+
if (!mTrackPtr)
|
|
103
|
+
{
|
|
104
|
+
Napi::Error::New(info.Env(), "mid() called on destroyed track").ThrowAsJavaScriptException();
|
|
105
|
+
return info.Env().Null();
|
|
106
|
+
}
|
|
107
|
+
|
|
117
108
|
Napi::Env env = info.Env();
|
|
118
109
|
return Napi::String::New(env, mTrackPtr->mid());
|
|
119
110
|
}
|
|
120
111
|
|
|
121
112
|
Napi::Value TrackWrapper::type(const Napi::CallbackInfo &info)
|
|
122
113
|
{
|
|
114
|
+
if (!mTrackPtr)
|
|
115
|
+
{
|
|
116
|
+
Napi::Error::New(info.Env(), "type() called on destroyed track").ThrowAsJavaScriptException();
|
|
117
|
+
return info.Env().Null();
|
|
118
|
+
}
|
|
119
|
+
|
|
123
120
|
Napi::Env env = info.Env();
|
|
124
121
|
return Napi::String::New(env, mTrackPtr->description().type());
|
|
125
122
|
}
|
|
@@ -128,7 +125,7 @@ Napi::Value TrackWrapper::sendMessage(const Napi::CallbackInfo &info)
|
|
|
128
125
|
{
|
|
129
126
|
if (!mTrackPtr)
|
|
130
127
|
{
|
|
131
|
-
Napi::Error::New(info.Env(), "
|
|
128
|
+
Napi::Error::New(info.Env(), "sendMessage() called on destroyed track").ThrowAsJavaScriptException();
|
|
132
129
|
return info.Env().Null();
|
|
133
130
|
}
|
|
134
131
|
|
|
@@ -148,7 +145,7 @@ Napi::Value TrackWrapper::sendMessage(const Napi::CallbackInfo &info)
|
|
|
148
145
|
}
|
|
149
146
|
catch (std::exception &ex)
|
|
150
147
|
{
|
|
151
|
-
Napi::Error::New(env, std::string("libdatachannel error while sending track
|
|
148
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending track message: ") + ex.what()).ThrowAsJavaScriptException();
|
|
152
149
|
return Napi::Boolean::New(info.Env(), false);
|
|
153
150
|
}
|
|
154
151
|
}
|
|
@@ -157,7 +154,7 @@ Napi::Value TrackWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
|
|
|
157
154
|
{
|
|
158
155
|
if (!mTrackPtr)
|
|
159
156
|
{
|
|
160
|
-
Napi::Error::New(info.Env(), "
|
|
157
|
+
Napi::Error::New(info.Env(), "sendMessageBinary() called on destroyed track").ThrowAsJavaScriptException();
|
|
161
158
|
return info.Env().Null();
|
|
162
159
|
}
|
|
163
160
|
|
|
@@ -177,7 +174,7 @@ Napi::Value TrackWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
|
|
|
177
174
|
}
|
|
178
175
|
catch (std::exception &ex)
|
|
179
176
|
{
|
|
180
|
-
Napi::Error::New(env, std::string("libdatachannel error while sending track
|
|
177
|
+
Napi::Error::New(env, std::string("libdatachannel error while sending track message: ") + ex.what()).ThrowAsJavaScriptException();
|
|
181
178
|
return Napi::Boolean::New(info.Env(), false);
|
|
182
179
|
}
|
|
183
180
|
}
|
|
@@ -185,18 +182,31 @@ Napi::Value TrackWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
|
|
|
185
182
|
Napi::Value TrackWrapper::isOpen(const Napi::CallbackInfo &info)
|
|
186
183
|
{
|
|
187
184
|
Napi::Env env = info.Env();
|
|
185
|
+
|
|
186
|
+
if (!mTrackPtr)
|
|
187
|
+
{
|
|
188
|
+
return Napi::Boolean::New(env, false);
|
|
189
|
+
}
|
|
190
|
+
|
|
188
191
|
return Napi::Boolean::New(env, mTrackPtr->isOpen());
|
|
189
192
|
}
|
|
190
193
|
|
|
191
194
|
Napi::Value TrackWrapper::isClosed(const Napi::CallbackInfo &info)
|
|
192
195
|
{
|
|
193
196
|
Napi::Env env = info.Env();
|
|
197
|
+
|
|
198
|
+
if (!mTrackPtr)
|
|
199
|
+
{
|
|
200
|
+
return Napi::Boolean::New(env, true);
|
|
201
|
+
}
|
|
202
|
+
|
|
194
203
|
return Napi::Boolean::New(env, mTrackPtr->isClosed());
|
|
195
204
|
}
|
|
196
205
|
|
|
197
206
|
Napi::Value TrackWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
198
207
|
{
|
|
199
208
|
Napi::Env env = info.Env();
|
|
209
|
+
|
|
200
210
|
if (!mTrackPtr)
|
|
201
211
|
{
|
|
202
212
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -208,13 +218,19 @@ Napi::Value TrackWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
|
208
218
|
}
|
|
209
219
|
catch (std::exception &ex)
|
|
210
220
|
{
|
|
211
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
221
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
212
222
|
return Napi::Number::New(info.Env(), 0);
|
|
213
223
|
}
|
|
214
224
|
}
|
|
215
225
|
|
|
216
226
|
Napi::Value TrackWrapper::requestKeyframe(const Napi::CallbackInfo &info)
|
|
217
227
|
{
|
|
228
|
+
if (!mTrackPtr)
|
|
229
|
+
{
|
|
230
|
+
Napi::Error::New(info.Env(), "requestKeyframe() called on destroyed track").ThrowAsJavaScriptException();
|
|
231
|
+
return info.Env().Null();
|
|
232
|
+
}
|
|
233
|
+
|
|
218
234
|
Napi::Env env = info.Env();
|
|
219
235
|
return Napi::Boolean::New(env, mTrackPtr->requestKeyframe());
|
|
220
236
|
}
|
|
@@ -223,7 +239,7 @@ void TrackWrapper::setMediaHandler(const Napi::CallbackInfo &info)
|
|
|
223
239
|
{
|
|
224
240
|
if (!mTrackPtr)
|
|
225
241
|
{
|
|
226
|
-
Napi::Error::New(info.Env(), "
|
|
242
|
+
Napi::Error::New(info.Env(), "setMediaHandler() called on destroyed track").ThrowAsJavaScriptException();
|
|
227
243
|
return;
|
|
228
244
|
}
|
|
229
245
|
|
|
@@ -232,7 +248,7 @@ void TrackWrapper::setMediaHandler(const Napi::CallbackInfo &info)
|
|
|
232
248
|
|
|
233
249
|
if (length < 1 || !info[0].IsObject())
|
|
234
250
|
{
|
|
235
|
-
Napi::TypeError::New(env, "
|
|
251
|
+
Napi::TypeError::New(env, "MediaHandler class instance expected").ThrowAsJavaScriptException();
|
|
236
252
|
return;
|
|
237
253
|
}
|
|
238
254
|
|
|
@@ -242,6 +258,12 @@ void TrackWrapper::setMediaHandler(const Napi::CallbackInfo &info)
|
|
|
242
258
|
|
|
243
259
|
void TrackWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
244
260
|
{
|
|
261
|
+
if (!mTrackPtr)
|
|
262
|
+
{
|
|
263
|
+
Napi::Error::New(info.Env(), "onOpen() called on destroyed track").ThrowAsJavaScriptException();
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
245
267
|
Napi::Env env = info.Env();
|
|
246
268
|
int length = info.Length();
|
|
247
269
|
|
|
@@ -254,11 +276,10 @@ void TrackWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
|
254
276
|
// Callback
|
|
255
277
|
mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
256
278
|
|
|
257
|
-
mTrackPtr->onOpen([&]()
|
|
258
|
-
{
|
|
279
|
+
mTrackPtr->onOpen([&]() {
|
|
259
280
|
if (mOnOpenCallback)
|
|
260
281
|
mOnOpenCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
261
|
-
// Check the
|
|
282
|
+
// Check the track is not closed
|
|
262
283
|
if(instances.find(this) == instances.end())
|
|
263
284
|
throw ThreadSafeCallback::CancelException();
|
|
264
285
|
|
|
@@ -270,6 +291,12 @@ void TrackWrapper::onOpen(const Napi::CallbackInfo &info)
|
|
|
270
291
|
|
|
271
292
|
void TrackWrapper::onClosed(const Napi::CallbackInfo &info)
|
|
272
293
|
{
|
|
294
|
+
if (!mTrackPtr)
|
|
295
|
+
{
|
|
296
|
+
Napi::Error::New(info.Env(), "onClosed() called on destroyed track").ThrowAsJavaScriptException();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
273
300
|
Napi::Env env = info.Env();
|
|
274
301
|
int length = info.Length();
|
|
275
302
|
|
|
@@ -282,11 +309,25 @@ void TrackWrapper::onClosed(const Napi::CallbackInfo &info)
|
|
|
282
309
|
// Callback
|
|
283
310
|
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
284
311
|
|
|
285
|
-
|
|
312
|
+
mTrackPtr->onClosed([&]() {
|
|
313
|
+
if (mOnClosedCallback)
|
|
314
|
+
mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
|
|
315
|
+
// Do not check if the data channel has been closed here
|
|
316
|
+
|
|
317
|
+
// This will run in main thread and needs to construct the
|
|
318
|
+
// arguments for the call
|
|
319
|
+
args = {};
|
|
320
|
+
}); });
|
|
286
321
|
}
|
|
287
322
|
|
|
288
323
|
void TrackWrapper::onError(const Napi::CallbackInfo &info)
|
|
289
324
|
{
|
|
325
|
+
if (!mTrackPtr)
|
|
326
|
+
{
|
|
327
|
+
Napi::Error::New(info.Env(), "onError() called on destroyed track").ThrowAsJavaScriptException();
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
290
331
|
Napi::Env env = info.Env();
|
|
291
332
|
int length = info.Length();
|
|
292
333
|
|
|
@@ -299,11 +340,10 @@ void TrackWrapper::onError(const Napi::CallbackInfo &info)
|
|
|
299
340
|
// Callback
|
|
300
341
|
mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
301
342
|
|
|
302
|
-
mTrackPtr->onError([&](const std::string &error)
|
|
303
|
-
{
|
|
343
|
+
mTrackPtr->onError([&](const std::string &error) {
|
|
304
344
|
if (mOnErrorCallback)
|
|
305
345
|
mOnErrorCallback->call([this, error](Napi::Env env, std::vector<napi_value> &args) {
|
|
306
|
-
// Check the
|
|
346
|
+
// Check the track is not closed
|
|
307
347
|
if(instances.find(this) == instances.end())
|
|
308
348
|
throw ThreadSafeCallback::CancelException();
|
|
309
349
|
|
|
@@ -315,6 +355,12 @@ void TrackWrapper::onError(const Napi::CallbackInfo &info)
|
|
|
315
355
|
|
|
316
356
|
void TrackWrapper::onMessage(const Napi::CallbackInfo &info)
|
|
317
357
|
{
|
|
358
|
+
if (!mTrackPtr)
|
|
359
|
+
{
|
|
360
|
+
Napi::Error::New(info.Env(), "onMessage() called on destroyed track").ThrowAsJavaScriptException();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
|
|
318
364
|
Napi::Env env = info.Env();
|
|
319
365
|
int length = info.Length();
|
|
320
366
|
|
|
@@ -327,26 +373,19 @@ void TrackWrapper::onMessage(const Napi::CallbackInfo &info)
|
|
|
327
373
|
// Callback
|
|
328
374
|
mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
329
375
|
|
|
330
|
-
mTrackPtr->onMessage([&](
|
|
331
|
-
{
|
|
376
|
+
mTrackPtr->onMessage([&](std::variant<rtc::binary, std::string> message) {
|
|
332
377
|
if (mOnMessageCallback)
|
|
333
|
-
mOnMessageCallback->call([this, message](Napi::Env env, std::vector<napi_value> &args) {
|
|
334
|
-
// Check the
|
|
378
|
+
mOnMessageCallback->call([this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args) {
|
|
379
|
+
// Check the track is not closed
|
|
335
380
|
if(instances.find(this) == instances.end())
|
|
336
381
|
throw ThreadSafeCallback::CancelException();
|
|
337
382
|
|
|
338
383
|
// This will run in main thread and needs to construct the
|
|
339
384
|
// arguments for the call
|
|
340
|
-
|
|
341
|
-
if (std::holds_alternative<std::string>(message))
|
|
342
|
-
{
|
|
343
|
-
// Track will always send message as binary
|
|
344
|
-
// So this code is not needed actually
|
|
345
|
-
args = {Napi::String::New(env, std::get<std::string>(message))};
|
|
346
|
-
}
|
|
347
|
-
else
|
|
385
|
+
if (std::holds_alternative<rtc::binary>(message)) // Track will always receive messages as binary
|
|
348
386
|
{
|
|
349
|
-
|
|
387
|
+
auto bin = std::get<rtc::binary>(std::move(message));
|
|
388
|
+
args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
|
|
350
389
|
}
|
|
351
390
|
}); });
|
|
352
|
-
}
|
|
391
|
+
}
|