node-datachannel 0.3.1 → 0.3.4
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/API.md +214 -0
- package/BULDING.md +19 -0
- package/CMakeLists.txt +2 -2
- package/README.md +28 -250
- 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 +101 -100
- 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
|
@@ -63,7 +63,7 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
63
63
|
// We expect (String, Object, Function) as param
|
|
64
64
|
if (length < 2 || !info[0].IsString() || !info[1].IsObject())
|
|
65
65
|
{
|
|
66
|
-
Napi::TypeError::New(env, "Peer Name (String)
|
|
66
|
+
Napi::TypeError::New(env, "Peer Name (String) and Configuration (Object) expected").ThrowAsJavaScriptException();
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -182,7 +182,11 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
182
182
|
|
|
183
183
|
// Max Message Size
|
|
184
184
|
if (config.Get("maxMessageSize").IsNumber())
|
|
185
|
-
rtcConfig.maxMessageSize = config.Get("maxMessageSize").As<Napi::Number>().
|
|
185
|
+
rtcConfig.maxMessageSize = config.Get("maxMessageSize").As<Napi::Number>().Int32Value();
|
|
186
|
+
|
|
187
|
+
// MTU
|
|
188
|
+
if (config.Get("mtu").IsNumber())
|
|
189
|
+
rtcConfig.mtu = config.Get("mtu").As<Napi::Number>().Int32Value();
|
|
186
190
|
|
|
187
191
|
// ICE transport policy
|
|
188
192
|
if (!config.Get("iceTransportPolicy").IsUndefined())
|
|
@@ -211,31 +215,10 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
211
215
|
}
|
|
212
216
|
catch (std::exception &ex)
|
|
213
217
|
{
|
|
214
|
-
Napi::Error::New(env, std::string("libdatachannel error while creating
|
|
218
|
+
Napi::Error::New(env, std::string("libdatachannel error while creating peer connection: ") + ex.what()).ThrowAsJavaScriptException();
|
|
215
219
|
return;
|
|
216
220
|
}
|
|
217
221
|
|
|
218
|
-
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state) {
|
|
219
|
-
if (mOnStateChangeCallback)
|
|
220
|
-
mOnStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
221
|
-
// Check the peer connection is not closed
|
|
222
|
-
if(instances.find(this) == instances.end())
|
|
223
|
-
throw ThreadSafeCallback::CancelException();
|
|
224
|
-
|
|
225
|
-
if(mDoCloseFlag && state == rtc::PeerConnection::State::Closed)
|
|
226
|
-
cleanCbsAndEraseInstance();
|
|
227
|
-
|
|
228
|
-
// This will run in main thread and needs to construct the
|
|
229
|
-
// arguments for the call
|
|
230
|
-
std::ostringstream stream;
|
|
231
|
-
stream << state;
|
|
232
|
-
args = {Napi::String::New(env, stream.str())};
|
|
233
|
-
});
|
|
234
|
-
else {
|
|
235
|
-
if(mDoCloseFlag && state == rtc::PeerConnection::State::Closed)
|
|
236
|
-
cleanCbsAndEraseInstance();
|
|
237
|
-
} });
|
|
238
|
-
|
|
239
222
|
instances.insert(this);
|
|
240
223
|
}
|
|
241
224
|
|
|
@@ -246,26 +229,20 @@ PeerConnectionWrapper::~PeerConnectionWrapper()
|
|
|
246
229
|
|
|
247
230
|
void PeerConnectionWrapper::doClose()
|
|
248
231
|
{
|
|
249
|
-
if (mRtcPeerConnPtr
|
|
232
|
+
if (mRtcPeerConnPtr)
|
|
250
233
|
{
|
|
251
234
|
try
|
|
252
235
|
{
|
|
253
|
-
mDoCloseFlag = true;
|
|
254
236
|
mRtcPeerConnPtr->close();
|
|
255
|
-
|
|
256
|
-
// Resetting in cleanCbsAndEraseInstance causes a deadlock
|
|
257
237
|
mRtcPeerConnPtr.reset();
|
|
258
238
|
}
|
|
259
239
|
catch (std::exception &ex)
|
|
260
240
|
{
|
|
261
|
-
std::
|
|
241
|
+
std::cerr << std::string("libdatachannel error while closing peer connection: ") + ex.what() << std::endl;
|
|
262
242
|
return;
|
|
263
243
|
}
|
|
264
244
|
}
|
|
265
|
-
}
|
|
266
245
|
|
|
267
|
-
void PeerConnectionWrapper::cleanCbsAndEraseInstance()
|
|
268
|
-
{
|
|
269
246
|
mOnLocalDescriptionCallback.reset();
|
|
270
247
|
mOnLocalCandidateCallback.reset();
|
|
271
248
|
mOnStateChangeCallback.reset();
|
|
@@ -274,8 +251,6 @@ void PeerConnectionWrapper::cleanCbsAndEraseInstance()
|
|
|
274
251
|
mOnTrackCallback.reset();
|
|
275
252
|
|
|
276
253
|
instances.erase(this);
|
|
277
|
-
|
|
278
|
-
mDoCloseFlag = false;
|
|
279
254
|
}
|
|
280
255
|
|
|
281
256
|
void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
@@ -286,14 +261,14 @@ void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
|
286
261
|
void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
287
262
|
{
|
|
288
263
|
Napi::Env env = info.Env();
|
|
264
|
+
int length = info.Length();
|
|
265
|
+
|
|
289
266
|
if (!mRtcPeerConnPtr)
|
|
290
267
|
{
|
|
291
|
-
Napi::Error::New(
|
|
268
|
+
Napi::Error::New(env, "setLocalDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
292
269
|
return;
|
|
293
270
|
}
|
|
294
271
|
|
|
295
|
-
int length = info.Length();
|
|
296
|
-
|
|
297
272
|
rtc::Description::Type type = rtc::Description::Type::Unspec;
|
|
298
273
|
|
|
299
274
|
// optional
|
|
@@ -322,13 +297,14 @@ void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
|
322
297
|
void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
323
298
|
{
|
|
324
299
|
Napi::Env env = info.Env();
|
|
300
|
+
int length = info.Length();
|
|
301
|
+
|
|
325
302
|
if (!mRtcPeerConnPtr)
|
|
326
303
|
{
|
|
327
|
-
Napi::Error::New(
|
|
304
|
+
Napi::Error::New(env, "setRemoteDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
328
305
|
return;
|
|
329
306
|
}
|
|
330
307
|
|
|
331
|
-
int length = info.Length();
|
|
332
308
|
if (length < 2 || !info[0].IsString() || !info[1].IsString())
|
|
333
309
|
{
|
|
334
310
|
Napi::TypeError::New(info.Env(), "String,String expected").ThrowAsJavaScriptException();
|
|
@@ -345,7 +321,7 @@ void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
|
345
321
|
}
|
|
346
322
|
catch (std::exception &ex)
|
|
347
323
|
{
|
|
348
|
-
Napi::Error::New(env, std::string("libdatachannel error while adding remote
|
|
324
|
+
Napi::Error::New(env, std::string("libdatachannel error while adding remote description: ") + ex.what()).ThrowAsJavaScriptException();
|
|
349
325
|
return;
|
|
350
326
|
}
|
|
351
327
|
}
|
|
@@ -353,7 +329,13 @@ void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
|
353
329
|
Napi::Value PeerConnectionWrapper::localDescription(const Napi::CallbackInfo &info)
|
|
354
330
|
{
|
|
355
331
|
Napi::Env env = info.Env();
|
|
356
|
-
|
|
332
|
+
|
|
333
|
+
std::optional<rtc::Description> desc = mRtcPeerConnPtr ? mRtcPeerConnPtr->localDescription() : std::nullopt;
|
|
334
|
+
|
|
335
|
+
// Return JS null if no description
|
|
336
|
+
if (!desc.has_value()) {
|
|
337
|
+
return env.Null();
|
|
338
|
+
}
|
|
357
339
|
|
|
358
340
|
Napi::Object obj = Napi::Object::New(env);
|
|
359
341
|
obj.Set("type", desc->typeString());
|
|
@@ -364,16 +346,17 @@ Napi::Value PeerConnectionWrapper::localDescription(const Napi::CallbackInfo &in
|
|
|
364
346
|
void PeerConnectionWrapper::addRemoteCandidate(const Napi::CallbackInfo &info)
|
|
365
347
|
{
|
|
366
348
|
Napi::Env env = info.Env();
|
|
349
|
+
int length = info.Length();
|
|
350
|
+
|
|
367
351
|
if (!mRtcPeerConnPtr)
|
|
368
352
|
{
|
|
369
|
-
Napi::Error::New(
|
|
353
|
+
Napi::Error::New(env, "addRemoteCandidate() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
370
354
|
return;
|
|
371
355
|
}
|
|
372
356
|
|
|
373
|
-
int length = info.Length();
|
|
374
357
|
if (length < 2 || !info[0].IsString() || !info[1].IsString())
|
|
375
358
|
{
|
|
376
|
-
Napi::TypeError::New(info.Env(), "String,String expected").ThrowAsJavaScriptException();
|
|
359
|
+
Napi::TypeError::New(info.Env(), "String, String expected").ThrowAsJavaScriptException();
|
|
377
360
|
return;
|
|
378
361
|
}
|
|
379
362
|
|
|
@@ -385,22 +368,22 @@ void PeerConnectionWrapper::addRemoteCandidate(const Napi::CallbackInfo &info)
|
|
|
385
368
|
}
|
|
386
369
|
catch (std::exception &ex)
|
|
387
370
|
{
|
|
388
|
-
Napi::Error::New(env, std::string("libdatachannel error while adding remote candidate
|
|
371
|
+
Napi::Error::New(env, std::string("libdatachannel error while adding remote candidate: ") + ex.what()).ThrowAsJavaScriptException();
|
|
389
372
|
return;
|
|
390
373
|
}
|
|
391
374
|
}
|
|
392
375
|
|
|
393
376
|
Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &info)
|
|
394
377
|
{
|
|
378
|
+
Napi::Env env = info.Env();
|
|
379
|
+
int length = info.Length();
|
|
380
|
+
|
|
395
381
|
if (!mRtcPeerConnPtr)
|
|
396
382
|
{
|
|
397
|
-
Napi::Error::New(
|
|
383
|
+
Napi::Error::New(env, "createDataChannel() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
398
384
|
return info.Env().Null();
|
|
399
385
|
}
|
|
400
386
|
|
|
401
|
-
Napi::Env env = info.Env();
|
|
402
|
-
int length = info.Length();
|
|
403
|
-
|
|
404
387
|
if (length < 1 || !info[0].IsString())
|
|
405
388
|
{
|
|
406
389
|
Napi::TypeError::New(env, "Data Channel Label expected").ThrowAsJavaScriptException();
|
|
@@ -554,7 +537,7 @@ Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &i
|
|
|
554
537
|
}
|
|
555
538
|
catch (std::exception &ex)
|
|
556
539
|
{
|
|
557
|
-
Napi::Error::New(env, std::string("libdatachannel error while creating datachannel
|
|
540
|
+
Napi::Error::New(env, std::string("libdatachannel error while creating datachannel: ") + ex.what()).ThrowAsJavaScriptException();
|
|
558
541
|
return info.Env().Null();
|
|
559
542
|
}
|
|
560
543
|
}
|
|
@@ -564,6 +547,12 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
564
547
|
Napi::Env env = info.Env();
|
|
565
548
|
int length = info.Length();
|
|
566
549
|
|
|
550
|
+
if (!mRtcPeerConnPtr)
|
|
551
|
+
{
|
|
552
|
+
Napi::Error::New(env, "onLocalDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
567
556
|
if (length < 1 || !info[0].IsFunction())
|
|
568
557
|
{
|
|
569
558
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -573,9 +562,9 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
573
562
|
// Callback
|
|
574
563
|
mOnLocalDescriptionCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
575
564
|
|
|
576
|
-
mRtcPeerConnPtr->onLocalDescription([&](
|
|
565
|
+
mRtcPeerConnPtr->onLocalDescription([&](rtc::Description sdp) {
|
|
577
566
|
if (mOnLocalDescriptionCallback)
|
|
578
|
-
mOnLocalDescriptionCallback->call([this, sdp](Napi::Env env, std::vector<napi_value> &args) {
|
|
567
|
+
mOnLocalDescriptionCallback->call([this, sdp = std::move(sdp)](Napi::Env env, std::vector<napi_value> &args) {
|
|
579
568
|
// Check the peer connection is not closed
|
|
580
569
|
if(instances.find(this) == instances.end())
|
|
581
570
|
throw ThreadSafeCallback::CancelException();
|
|
@@ -593,6 +582,12 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
593
582
|
Napi::Env env = info.Env();
|
|
594
583
|
int length = info.Length();
|
|
595
584
|
|
|
585
|
+
if (!mRtcPeerConnPtr)
|
|
586
|
+
{
|
|
587
|
+
Napi::Error::New(env, "onLocalCandidate() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
596
591
|
if (length < 1 || !info[0].IsFunction())
|
|
597
592
|
{
|
|
598
593
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -602,9 +597,9 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
602
597
|
// Callback
|
|
603
598
|
mOnLocalCandidateCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
604
599
|
|
|
605
|
-
mRtcPeerConnPtr->onLocalCandidate([&](
|
|
600
|
+
mRtcPeerConnPtr->onLocalCandidate([&](rtc::Candidate cand) {
|
|
606
601
|
if (mOnLocalCandidateCallback)
|
|
607
|
-
mOnLocalCandidateCallback->call([this,
|
|
602
|
+
mOnLocalCandidateCallback->call([this, cand = std::move(cand)](Napi::Env env, std::vector<napi_value> &args) {
|
|
608
603
|
// Check the peer connection is not closed
|
|
609
604
|
if(instances.find(this) == instances.end())
|
|
610
605
|
throw ThreadSafeCallback::CancelException();
|
|
@@ -612,8 +607,8 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
612
607
|
// This will run in main thread and needs to construct the
|
|
613
608
|
// arguments for the call
|
|
614
609
|
args = {
|
|
615
|
-
Napi::String::New(env, std::string(
|
|
616
|
-
Napi::String::New(env,
|
|
610
|
+
Napi::String::New(env, std::string(cand)),
|
|
611
|
+
Napi::String::New(env, cand.mid())};
|
|
617
612
|
}); });
|
|
618
613
|
}
|
|
619
614
|
|
|
@@ -622,6 +617,12 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
622
617
|
Napi::Env env = info.Env();
|
|
623
618
|
int length = info.Length();
|
|
624
619
|
|
|
620
|
+
if (!mRtcPeerConnPtr)
|
|
621
|
+
{
|
|
622
|
+
Napi::Error::New(env, "onStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
|
|
625
626
|
if (length < 1 || !info[0].IsFunction())
|
|
626
627
|
{
|
|
627
628
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -631,7 +632,19 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
631
632
|
// Callback
|
|
632
633
|
mOnStateChangeCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
633
634
|
|
|
634
|
-
|
|
635
|
+
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state) {
|
|
636
|
+
if (mOnStateChangeCallback)
|
|
637
|
+
mOnStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
638
|
+
// Check the peer connection is not closed but still allow a call for State::Closed
|
|
639
|
+
if(state != rtc::PeerConnection::State::Closed && instances.find(this) == instances.end())
|
|
640
|
+
throw ThreadSafeCallback::CancelException();
|
|
641
|
+
|
|
642
|
+
// This will run in main thread and needs to construct the
|
|
643
|
+
// arguments for the call
|
|
644
|
+
std::ostringstream stream;
|
|
645
|
+
stream << state;
|
|
646
|
+
args = {Napi::String::New(env, stream.str())};
|
|
647
|
+
}); });
|
|
635
648
|
}
|
|
636
649
|
|
|
637
650
|
void PeerConnectionWrapper::onSignalingStateChange(const Napi::CallbackInfo &info)
|
|
@@ -639,6 +652,12 @@ void PeerConnectionWrapper::onSignalingStateChange(const Napi::CallbackInfo &inf
|
|
|
639
652
|
Napi::Env env = info.Env();
|
|
640
653
|
int length = info.Length();
|
|
641
654
|
|
|
655
|
+
if (!mRtcPeerConnPtr)
|
|
656
|
+
{
|
|
657
|
+
Napi::Error::New(env, "onSignalingStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
|
|
642
661
|
if (length < 1 || !info[0].IsFunction())
|
|
643
662
|
{
|
|
644
663
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -668,6 +687,12 @@ void PeerConnectionWrapper::onGatheringStateChange(const Napi::CallbackInfo &inf
|
|
|
668
687
|
Napi::Env env = info.Env();
|
|
669
688
|
int length = info.Length();
|
|
670
689
|
|
|
690
|
+
if (!mRtcPeerConnPtr)
|
|
691
|
+
{
|
|
692
|
+
Napi::Error::New(env, "onGatheringStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
|
|
671
696
|
if (length < 1 || !info[0].IsFunction())
|
|
672
697
|
{
|
|
673
698
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -697,6 +722,12 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
697
722
|
Napi::Env env = info.Env();
|
|
698
723
|
int length = info.Length();
|
|
699
724
|
|
|
725
|
+
if (!mRtcPeerConnPtr)
|
|
726
|
+
{
|
|
727
|
+
Napi::Error::New(env, "onDataChannel() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
|
|
700
731
|
if (length < 1 || !info[0].IsFunction())
|
|
701
732
|
{
|
|
702
733
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -725,6 +756,7 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
725
756
|
Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
726
757
|
{
|
|
727
758
|
Napi::Env env = info.Env();
|
|
759
|
+
|
|
728
760
|
if (!mRtcPeerConnPtr)
|
|
729
761
|
{
|
|
730
762
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -736,7 +768,7 @@ Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
|
736
768
|
}
|
|
737
769
|
catch (std::exception &ex)
|
|
738
770
|
{
|
|
739
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
771
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
740
772
|
return Napi::Number::New(info.Env(), 0);
|
|
741
773
|
}
|
|
742
774
|
}
|
|
@@ -744,6 +776,7 @@ Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
|
744
776
|
Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
745
777
|
{
|
|
746
778
|
Napi::Env env = info.Env();
|
|
779
|
+
|
|
747
780
|
if (!mRtcPeerConnPtr)
|
|
748
781
|
{
|
|
749
782
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -755,7 +788,7 @@ Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
|
755
788
|
}
|
|
756
789
|
catch (std::exception &ex)
|
|
757
790
|
{
|
|
758
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
791
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
759
792
|
return Napi::Number::New(info.Env(), 0);
|
|
760
793
|
}
|
|
761
794
|
}
|
|
@@ -763,6 +796,7 @@ Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
|
763
796
|
Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
764
797
|
{
|
|
765
798
|
Napi::Env env = info.Env();
|
|
799
|
+
|
|
766
800
|
if (!mRtcPeerConnPtr)
|
|
767
801
|
{
|
|
768
802
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -774,7 +808,7 @@ Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
|
774
808
|
}
|
|
775
809
|
catch (std::exception &ex)
|
|
776
810
|
{
|
|
777
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
811
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
778
812
|
return Napi::Number::New(info.Env(), -1);
|
|
779
813
|
}
|
|
780
814
|
}
|
|
@@ -782,16 +816,17 @@ Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
|
782
816
|
Napi::Value PeerConnectionWrapper::getSelectedCandidatePair(const Napi::CallbackInfo &info)
|
|
783
817
|
{
|
|
784
818
|
Napi::Env env = info.Env();
|
|
819
|
+
|
|
785
820
|
if (!mRtcPeerConnPtr)
|
|
786
821
|
{
|
|
787
|
-
return
|
|
822
|
+
return env.Null();
|
|
788
823
|
}
|
|
789
824
|
|
|
790
825
|
try
|
|
791
826
|
{
|
|
792
827
|
rtc::Candidate local, remote;
|
|
793
828
|
if (!mRtcPeerConnPtr->getSelectedCandidatePair(&local, &remote))
|
|
794
|
-
return
|
|
829
|
+
return env.Null();
|
|
795
830
|
|
|
796
831
|
Napi::Object retvalue = Napi::Object::New(env);
|
|
797
832
|
Napi::Object localObj = Napi::Object::New(env);
|
|
@@ -814,7 +849,7 @@ Napi::Value PeerConnectionWrapper::getSelectedCandidatePair(const Napi::Callback
|
|
|
814
849
|
}
|
|
815
850
|
catch (std::exception &ex)
|
|
816
851
|
{
|
|
817
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
852
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
818
853
|
return Napi::Number::New(info.Env(), -1);
|
|
819
854
|
}
|
|
820
855
|
}
|
|
@@ -862,7 +897,7 @@ Napi::Value PeerConnectionWrapper::addTrack(const Napi::CallbackInfo &info)
|
|
|
862
897
|
|
|
863
898
|
if (!mRtcPeerConnPtr)
|
|
864
899
|
{
|
|
865
|
-
Napi::Error::New(
|
|
900
|
+
Napi::Error::New(env, "addTrack() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
866
901
|
return env.Null();
|
|
867
902
|
}
|
|
868
903
|
|
|
@@ -896,7 +931,7 @@ Napi::Value PeerConnectionWrapper::addTrack(const Napi::CallbackInfo &info)
|
|
|
896
931
|
}
|
|
897
932
|
catch (std::exception &ex)
|
|
898
933
|
{
|
|
899
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
934
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
900
935
|
return env.Null();
|
|
901
936
|
}
|
|
902
937
|
}
|
|
@@ -906,6 +941,12 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
906
941
|
Napi::Env env = info.Env();
|
|
907
942
|
int length = info.Length();
|
|
908
943
|
|
|
944
|
+
if (!mRtcPeerConnPtr)
|
|
945
|
+
{
|
|
946
|
+
Napi::Error::New(env, "onGatheringStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
|
|
909
950
|
if (length < 1 || !info[0].IsFunction())
|
|
910
951
|
{
|
|
911
952
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -915,8 +956,7 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
915
956
|
// Callback
|
|
916
957
|
mOnTrackCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
917
958
|
|
|
918
|
-
mRtcPeerConnPtr->onTrack([&](std::shared_ptr<rtc::Track> track)
|
|
919
|
-
{
|
|
959
|
+
mRtcPeerConnPtr->onTrack([&](std::shared_ptr<rtc::Track> track) {
|
|
920
960
|
if (mOnTrackCallback)
|
|
921
961
|
mOnTrackCallback->call([this, track](Napi::Env env, std::vector<napi_value> &args) {
|
|
922
962
|
// Check the peer connection is not closed
|
|
@@ -934,14 +974,14 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
934
974
|
Napi::Value PeerConnectionWrapper::hasMedia(const Napi::CallbackInfo &info)
|
|
935
975
|
{
|
|
936
976
|
Napi::Env env = info.Env();
|
|
937
|
-
return Napi::Boolean::New(env, mRtcPeerConnPtr->hasMedia());
|
|
977
|
+
return Napi::Boolean::New(env, mRtcPeerConnPtr ? mRtcPeerConnPtr->hasMedia() : false);
|
|
938
978
|
}
|
|
939
979
|
|
|
940
980
|
Napi::Value PeerConnectionWrapper::state(const Napi::CallbackInfo &info)
|
|
941
981
|
{
|
|
942
982
|
Napi::Env env = info.Env();
|
|
943
983
|
std::ostringstream stream;
|
|
944
|
-
stream << mRtcPeerConnPtr->state();
|
|
984
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->state() : rtc::PeerConnection::State::Closed);
|
|
945
985
|
return Napi::String::New(env, stream.str());
|
|
946
986
|
}
|
|
947
987
|
|
|
@@ -949,7 +989,7 @@ Napi::Value PeerConnectionWrapper::signalingState(const Napi::CallbackInfo &info
|
|
|
949
989
|
{
|
|
950
990
|
Napi::Env env = info.Env();
|
|
951
991
|
std::ostringstream stream;
|
|
952
|
-
stream << mRtcPeerConnPtr->signalingState();
|
|
992
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->signalingState() : rtc::PeerConnection::SignalingState::Stable);
|
|
953
993
|
return Napi::String::New(env, stream.str());
|
|
954
994
|
}
|
|
955
995
|
|
|
@@ -957,6 +997,6 @@ Napi::Value PeerConnectionWrapper::gatheringState(const Napi::CallbackInfo &info
|
|
|
957
997
|
{
|
|
958
998
|
Napi::Env env = info.Env();
|
|
959
999
|
std::ostringstream stream;
|
|
960
|
-
stream << mRtcPeerConnPtr->gatheringState();
|
|
1000
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->gatheringState() : rtc::PeerConnection::GatheringState::Complete);
|
|
961
1001
|
return Napi::String::New(env, stream.str());
|
|
962
1002
|
}
|
package/test/connectivity.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
1
2
|
const nodeDataChannel = require('../lib/index');
|
|
2
3
|
|
|
3
|
-
nodeDataChannel.initLogger(
|
|
4
|
+
nodeDataChannel.initLogger('Debug');
|
|
4
5
|
nodeDataChannel.preload();
|
|
5
6
|
|
|
6
7
|
let dc1 = null;
|
|
@@ -24,51 +25,51 @@ let dc2 = null;
|
|
|
24
25
|
// TURN Server Example (TCP) : turn:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT?transport=tcp
|
|
25
26
|
// TURN Server Example (TLS) : turns:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT
|
|
26
27
|
|
|
27
|
-
let peer1 = new nodeDataChannel.PeerConnection(
|
|
28
|
+
let peer1 = new nodeDataChannel.PeerConnection('Peer1', { iceServers: ['stun:stun.l.google.com:19302'] });
|
|
28
29
|
|
|
29
30
|
// Set Callbacks
|
|
30
31
|
peer1.onStateChange((state) => {
|
|
31
|
-
console.log(
|
|
32
|
+
console.log('Peer1 State:', state);
|
|
32
33
|
});
|
|
33
34
|
peer1.onGatheringStateChange((state) => {
|
|
34
|
-
console.log(
|
|
35
|
+
console.log('Peer1 GatheringState:', state);
|
|
35
36
|
});
|
|
36
37
|
peer1.onLocalDescription((sdp, type) => {
|
|
37
|
-
console.log(
|
|
38
|
+
console.log('Peer1 SDP:', sdp, ' Type:', type);
|
|
38
39
|
peer2.setRemoteDescription(sdp, type);
|
|
39
40
|
});
|
|
40
41
|
peer1.onLocalCandidate((candidate, mid) => {
|
|
41
|
-
console.log(
|
|
42
|
+
console.log('Peer1 Candidate:', candidate);
|
|
42
43
|
peer2.addRemoteCandidate(candidate, mid);
|
|
43
44
|
});
|
|
44
45
|
|
|
45
|
-
let peer2 = new nodeDataChannel.PeerConnection(
|
|
46
|
+
let peer2 = new nodeDataChannel.PeerConnection('Peer2', { iceServers: ['stun:stun.l.google.com:19302'] });
|
|
46
47
|
|
|
47
48
|
// Set Callbacks
|
|
48
49
|
peer2.onStateChange((state) => {
|
|
49
|
-
console.log(
|
|
50
|
+
console.log('Peer2 State:', state);
|
|
50
51
|
});
|
|
51
52
|
peer2.onGatheringStateChange((state) => {
|
|
52
|
-
console.log(
|
|
53
|
+
console.log('Peer2 GatheringState:', state);
|
|
53
54
|
});
|
|
54
55
|
peer2.onLocalDescription((sdp, type) => {
|
|
55
|
-
console.log(
|
|
56
|
+
console.log('Peer2 SDP:', sdp, ' Type:', type);
|
|
56
57
|
peer1.setRemoteDescription(sdp, type);
|
|
57
58
|
});
|
|
58
59
|
peer2.onLocalCandidate((candidate, mid) => {
|
|
59
|
-
console.log(
|
|
60
|
+
console.log('Peer2 Candidate:', candidate);
|
|
60
61
|
peer1.addRemoteCandidate(candidate, mid);
|
|
61
62
|
});
|
|
62
63
|
peer2.onDataChannel((dc) => {
|
|
63
|
-
console.log(
|
|
64
|
+
console.log('Peer2 Got DataChannel: ', dc.getLabel());
|
|
64
65
|
dc2 = dc;
|
|
65
66
|
dc2.onMessage((msg) => {
|
|
66
67
|
console.log('Peer2 Received Msg:', msg);
|
|
67
68
|
});
|
|
68
|
-
dc2.sendMessage(
|
|
69
|
+
dc2.sendMessage('Hello From Peer2');
|
|
69
70
|
dc2.onClosed(() => {
|
|
70
71
|
console.log('dc2 closed');
|
|
71
|
-
|
|
72
|
+
});
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
// DataChannel Options
|
|
@@ -80,16 +81,16 @@ peer2.onDataChannel((dc) => {
|
|
|
80
81
|
// maxPacketLifeTime?: number;
|
|
81
82
|
// maxRetransmits?: number;
|
|
82
83
|
// }
|
|
83
|
-
dc1 = peer1.createDataChannel(
|
|
84
|
+
dc1 = peer1.createDataChannel('test');
|
|
84
85
|
dc1.onOpen(() => {
|
|
85
|
-
dc1.sendMessage(
|
|
86
|
+
dc1.sendMessage('Hello from Peer1');
|
|
86
87
|
// Binary message: Use sendMessageBinary(Buffer)
|
|
87
88
|
});
|
|
88
89
|
dc1.onMessage((msg) => {
|
|
89
90
|
console.log('Peer1 Received Msg:', msg);
|
|
90
91
|
});
|
|
91
92
|
dc1.onClosed(() => {
|
|
92
|
-
|
|
93
|
+
console.log('dc1 closed');
|
|
93
94
|
});
|
|
94
95
|
|
|
95
96
|
setTimeout(() => {
|