node-datachannel 0.2.4 → 0.3.2
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/.editorconfig +12 -0
- package/.eslintignore +2 -0
- package/.eslintrc.js +8 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/workflows/build-linux.yml +3 -3
- package/.github/workflows/build-mac.yml +1 -1
- package/.github/workflows/build-win.yml +4 -4
- package/.github/workflows/lint.yml +22 -0
- package/.prettierrc.js +7 -0
- package/CMakeLists.txt +8 -2
- package/README.md +4 -4
- 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/datachannel-stream.js +23 -12
- package/lib/index.d.ts +113 -116
- package/lib/index.js +3 -2
- package/node_modules/detect-libc/package.json +1 -0
- package/node_modules/lru-cache/package.json +1 -2
- package/node_modules/minimist/index.js +6 -2
- package/node_modules/minimist/package.json +10 -11
- package/node_modules/minimist/readme.markdown +4 -1
- package/node_modules/minimist/test/proto.js +16 -0
- 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/node-abi/package.json +1 -0
- 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 +12 -4
- package/src/data-channel-wrapper.cpp +90 -40
- package/src/data-channel-wrapper.h +2 -0
- package/src/media-audio-wrapper.cpp +5 -5
- package/src/media-track-wrapper.cpp +96 -38
- package/src/media-track-wrapper.h +1 -0
- package/src/media-video-wrapper.cpp +5 -5
- package/src/peer-connection-wrapper.cpp +111 -54
- package/test/connectivity.js +22 -21
- package/test/test.js +25 -33
- 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
|
|
|
@@ -147,10 +147,6 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
147
147
|
std::string strType = proxyServer.Get("type").As<Napi::String>().ToString();
|
|
148
148
|
rtc::ProxyServer::Type type = rtc::ProxyServer::Type::Http;
|
|
149
149
|
|
|
150
|
-
if (strType == "None")
|
|
151
|
-
type = rtc::ProxyServer::Type::None;
|
|
152
|
-
if (strType == "Http")
|
|
153
|
-
type = rtc::ProxyServer::Type::Http;
|
|
154
150
|
if (strType == "Socks5")
|
|
155
151
|
type = rtc::ProxyServer::Type::Socks5;
|
|
156
152
|
|
|
@@ -176,6 +172,14 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
176
172
|
if (config.Get("enableIceTcp").IsBoolean())
|
|
177
173
|
rtcConfig.enableIceTcp = config.Get("enableIceTcp").As<Napi::Boolean>();
|
|
178
174
|
|
|
175
|
+
// enableIceUdpMux option
|
|
176
|
+
if (config.Get("enableIceUdpMux").IsBoolean())
|
|
177
|
+
rtcConfig.enableIceUdpMux = config.Get("enableIceUdpMux").As<Napi::Boolean>();
|
|
178
|
+
|
|
179
|
+
// disableAutoNegotiation option
|
|
180
|
+
if (config.Get("disableAutoNegotiation").IsBoolean())
|
|
181
|
+
rtcConfig.disableAutoNegotiation = config.Get("disableAutoNegotiation").As<Napi::Boolean>();
|
|
182
|
+
|
|
179
183
|
// Max Message Size
|
|
180
184
|
if (config.Get("maxMessageSize").IsNumber())
|
|
181
185
|
rtcConfig.maxMessageSize = config.Get("maxMessageSize").As<Napi::Number>().Uint32Value();
|
|
@@ -207,7 +211,7 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
207
211
|
}
|
|
208
212
|
catch (std::exception &ex)
|
|
209
213
|
{
|
|
210
|
-
Napi::Error::New(env, std::string("libdatachannel error while creating
|
|
214
|
+
Napi::Error::New(env, std::string("libdatachannel error while creating peer connection: ") + ex.what()).ThrowAsJavaScriptException();
|
|
211
215
|
return;
|
|
212
216
|
}
|
|
213
217
|
|
|
@@ -221,28 +225,28 @@ PeerConnectionWrapper::~PeerConnectionWrapper()
|
|
|
221
225
|
|
|
222
226
|
void PeerConnectionWrapper::doClose()
|
|
223
227
|
{
|
|
224
|
-
instances.erase(this);
|
|
225
|
-
|
|
226
228
|
if (mRtcPeerConnPtr)
|
|
227
229
|
{
|
|
228
230
|
try
|
|
229
231
|
{
|
|
230
|
-
mOnLocalDescriptionCallback.reset();
|
|
231
|
-
mOnLocalCandidateCallback.reset();
|
|
232
|
-
mOnStateChangeCallback.reset();
|
|
233
|
-
mOnGatheringStateChangeCallback.reset();
|
|
234
|
-
mOnDataChannelCallback.reset();
|
|
235
|
-
mOnTrackCallback.reset();
|
|
236
|
-
|
|
237
232
|
mRtcPeerConnPtr->close();
|
|
238
233
|
mRtcPeerConnPtr.reset();
|
|
239
234
|
}
|
|
240
235
|
catch (std::exception &ex)
|
|
241
236
|
{
|
|
242
|
-
std::
|
|
237
|
+
std::cerr << std::string("libdatachannel error while closing peer connection: ") + ex.what() << std::endl;
|
|
243
238
|
return;
|
|
244
239
|
}
|
|
245
240
|
}
|
|
241
|
+
|
|
242
|
+
mOnLocalDescriptionCallback.reset();
|
|
243
|
+
mOnLocalCandidateCallback.reset();
|
|
244
|
+
mOnStateChangeCallback.reset();
|
|
245
|
+
mOnGatheringStateChangeCallback.reset();
|
|
246
|
+
mOnDataChannelCallback.reset();
|
|
247
|
+
mOnTrackCallback.reset();
|
|
248
|
+
|
|
249
|
+
instances.erase(this);
|
|
246
250
|
}
|
|
247
251
|
|
|
248
252
|
void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
@@ -253,14 +257,14 @@ void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
|
253
257
|
void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
254
258
|
{
|
|
255
259
|
Napi::Env env = info.Env();
|
|
260
|
+
int length = info.Length();
|
|
261
|
+
|
|
256
262
|
if (!mRtcPeerConnPtr)
|
|
257
263
|
{
|
|
258
|
-
Napi::Error::New(
|
|
264
|
+
Napi::Error::New(env, "setLocalDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
259
265
|
return;
|
|
260
266
|
}
|
|
261
267
|
|
|
262
|
-
int length = info.Length();
|
|
263
|
-
|
|
264
268
|
rtc::Description::Type type = rtc::Description::Type::Unspec;
|
|
265
269
|
|
|
266
270
|
// optional
|
|
@@ -289,13 +293,14 @@ void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
|
289
293
|
void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
290
294
|
{
|
|
291
295
|
Napi::Env env = info.Env();
|
|
296
|
+
int length = info.Length();
|
|
297
|
+
|
|
292
298
|
if (!mRtcPeerConnPtr)
|
|
293
299
|
{
|
|
294
|
-
Napi::Error::New(
|
|
300
|
+
Napi::Error::New(env, "setRemoteDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
295
301
|
return;
|
|
296
302
|
}
|
|
297
303
|
|
|
298
|
-
int length = info.Length();
|
|
299
304
|
if (length < 2 || !info[0].IsString() || !info[1].IsString())
|
|
300
305
|
{
|
|
301
306
|
Napi::TypeError::New(info.Env(), "String,String expected").ThrowAsJavaScriptException();
|
|
@@ -312,7 +317,7 @@ void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
|
312
317
|
}
|
|
313
318
|
catch (std::exception &ex)
|
|
314
319
|
{
|
|
315
|
-
Napi::Error::New(env, std::string("libdatachannel error while adding remote
|
|
320
|
+
Napi::Error::New(env, std::string("libdatachannel error while adding remote description: ") + ex.what()).ThrowAsJavaScriptException();
|
|
316
321
|
return;
|
|
317
322
|
}
|
|
318
323
|
}
|
|
@@ -320,7 +325,13 @@ void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
|
320
325
|
Napi::Value PeerConnectionWrapper::localDescription(const Napi::CallbackInfo &info)
|
|
321
326
|
{
|
|
322
327
|
Napi::Env env = info.Env();
|
|
323
|
-
|
|
328
|
+
|
|
329
|
+
std::optional<rtc::Description> desc = mRtcPeerConnPtr ? mRtcPeerConnPtr->localDescription() : std::nullopt;
|
|
330
|
+
|
|
331
|
+
// Return JS null if no description
|
|
332
|
+
if (!desc.has_value()) {
|
|
333
|
+
return env.Null();
|
|
334
|
+
}
|
|
324
335
|
|
|
325
336
|
Napi::Object obj = Napi::Object::New(env);
|
|
326
337
|
obj.Set("type", desc->typeString());
|
|
@@ -331,16 +342,17 @@ Napi::Value PeerConnectionWrapper::localDescription(const Napi::CallbackInfo &in
|
|
|
331
342
|
void PeerConnectionWrapper::addRemoteCandidate(const Napi::CallbackInfo &info)
|
|
332
343
|
{
|
|
333
344
|
Napi::Env env = info.Env();
|
|
345
|
+
int length = info.Length();
|
|
346
|
+
|
|
334
347
|
if (!mRtcPeerConnPtr)
|
|
335
348
|
{
|
|
336
|
-
Napi::Error::New(
|
|
349
|
+
Napi::Error::New(env, "addRemoteCandidate() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
337
350
|
return;
|
|
338
351
|
}
|
|
339
352
|
|
|
340
|
-
int length = info.Length();
|
|
341
353
|
if (length < 2 || !info[0].IsString() || !info[1].IsString())
|
|
342
354
|
{
|
|
343
|
-
Napi::TypeError::New(info.Env(), "String,String expected").ThrowAsJavaScriptException();
|
|
355
|
+
Napi::TypeError::New(info.Env(), "String, String expected").ThrowAsJavaScriptException();
|
|
344
356
|
return;
|
|
345
357
|
}
|
|
346
358
|
|
|
@@ -352,22 +364,22 @@ void PeerConnectionWrapper::addRemoteCandidate(const Napi::CallbackInfo &info)
|
|
|
352
364
|
}
|
|
353
365
|
catch (std::exception &ex)
|
|
354
366
|
{
|
|
355
|
-
Napi::Error::New(env, std::string("libdatachannel error while adding remote candidate
|
|
367
|
+
Napi::Error::New(env, std::string("libdatachannel error while adding remote candidate: ") + ex.what()).ThrowAsJavaScriptException();
|
|
356
368
|
return;
|
|
357
369
|
}
|
|
358
370
|
}
|
|
359
371
|
|
|
360
372
|
Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &info)
|
|
361
373
|
{
|
|
374
|
+
Napi::Env env = info.Env();
|
|
375
|
+
int length = info.Length();
|
|
376
|
+
|
|
362
377
|
if (!mRtcPeerConnPtr)
|
|
363
378
|
{
|
|
364
|
-
Napi::Error::New(
|
|
379
|
+
Napi::Error::New(env, "createDataChannel() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
365
380
|
return info.Env().Null();
|
|
366
381
|
}
|
|
367
382
|
|
|
368
|
-
Napi::Env env = info.Env();
|
|
369
|
-
int length = info.Length();
|
|
370
|
-
|
|
371
383
|
if (length < 1 || !info[0].IsString())
|
|
372
384
|
{
|
|
373
385
|
Napi::TypeError::New(env, "Data Channel Label expected").ThrowAsJavaScriptException();
|
|
@@ -521,7 +533,7 @@ Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &i
|
|
|
521
533
|
}
|
|
522
534
|
catch (std::exception &ex)
|
|
523
535
|
{
|
|
524
|
-
Napi::Error::New(env, std::string("libdatachannel error while creating datachannel
|
|
536
|
+
Napi::Error::New(env, std::string("libdatachannel error while creating datachannel: ") + ex.what()).ThrowAsJavaScriptException();
|
|
525
537
|
return info.Env().Null();
|
|
526
538
|
}
|
|
527
539
|
}
|
|
@@ -531,6 +543,12 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
531
543
|
Napi::Env env = info.Env();
|
|
532
544
|
int length = info.Length();
|
|
533
545
|
|
|
546
|
+
if (!mRtcPeerConnPtr)
|
|
547
|
+
{
|
|
548
|
+
Napi::Error::New(env, "onLocalDescription() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
|
|
534
552
|
if (length < 1 || !info[0].IsFunction())
|
|
535
553
|
{
|
|
536
554
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -540,9 +558,9 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
540
558
|
// Callback
|
|
541
559
|
mOnLocalDescriptionCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
542
560
|
|
|
543
|
-
mRtcPeerConnPtr->onLocalDescription([&](
|
|
561
|
+
mRtcPeerConnPtr->onLocalDescription([&](rtc::Description sdp) {
|
|
544
562
|
if (mOnLocalDescriptionCallback)
|
|
545
|
-
mOnLocalDescriptionCallback->call([this, sdp](Napi::Env env, std::vector<napi_value> &args) {
|
|
563
|
+
mOnLocalDescriptionCallback->call([this, sdp = std::move(sdp)](Napi::Env env, std::vector<napi_value> &args) {
|
|
546
564
|
// Check the peer connection is not closed
|
|
547
565
|
if(instances.find(this) == instances.end())
|
|
548
566
|
throw ThreadSafeCallback::CancelException();
|
|
@@ -560,6 +578,12 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
560
578
|
Napi::Env env = info.Env();
|
|
561
579
|
int length = info.Length();
|
|
562
580
|
|
|
581
|
+
if (!mRtcPeerConnPtr)
|
|
582
|
+
{
|
|
583
|
+
Napi::Error::New(env, "onLocalCandidate() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
563
587
|
if (length < 1 || !info[0].IsFunction())
|
|
564
588
|
{
|
|
565
589
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -569,9 +593,9 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
569
593
|
// Callback
|
|
570
594
|
mOnLocalCandidateCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
571
595
|
|
|
572
|
-
mRtcPeerConnPtr->onLocalCandidate([&](
|
|
596
|
+
mRtcPeerConnPtr->onLocalCandidate([&](rtc::Candidate cand) {
|
|
573
597
|
if (mOnLocalCandidateCallback)
|
|
574
|
-
mOnLocalCandidateCallback->call([this,
|
|
598
|
+
mOnLocalCandidateCallback->call([this, cand = std::move(cand)](Napi::Env env, std::vector<napi_value> &args) {
|
|
575
599
|
// Check the peer connection is not closed
|
|
576
600
|
if(instances.find(this) == instances.end())
|
|
577
601
|
throw ThreadSafeCallback::CancelException();
|
|
@@ -579,8 +603,8 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
579
603
|
// This will run in main thread and needs to construct the
|
|
580
604
|
// arguments for the call
|
|
581
605
|
args = {
|
|
582
|
-
Napi::String::New(env, std::string(
|
|
583
|
-
Napi::String::New(env,
|
|
606
|
+
Napi::String::New(env, std::string(cand)),
|
|
607
|
+
Napi::String::New(env, cand.mid())};
|
|
584
608
|
}); });
|
|
585
609
|
}
|
|
586
610
|
|
|
@@ -589,6 +613,12 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
589
613
|
Napi::Env env = info.Env();
|
|
590
614
|
int length = info.Length();
|
|
591
615
|
|
|
616
|
+
if (!mRtcPeerConnPtr)
|
|
617
|
+
{
|
|
618
|
+
Napi::Error::New(env, "onStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
|
|
592
622
|
if (length < 1 || !info[0].IsFunction())
|
|
593
623
|
{
|
|
594
624
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -601,8 +631,8 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
601
631
|
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state) {
|
|
602
632
|
if (mOnStateChangeCallback)
|
|
603
633
|
mOnStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
604
|
-
// Check the peer connection is not closed
|
|
605
|
-
if(instances.find(this) == instances.end())
|
|
634
|
+
// Check the peer connection is not closed but still allow a call for State::Closed
|
|
635
|
+
if(state != rtc::PeerConnection::State::Closed && instances.find(this) == instances.end())
|
|
606
636
|
throw ThreadSafeCallback::CancelException();
|
|
607
637
|
|
|
608
638
|
// This will run in main thread and needs to construct the
|
|
@@ -618,6 +648,12 @@ void PeerConnectionWrapper::onSignalingStateChange(const Napi::CallbackInfo &inf
|
|
|
618
648
|
Napi::Env env = info.Env();
|
|
619
649
|
int length = info.Length();
|
|
620
650
|
|
|
651
|
+
if (!mRtcPeerConnPtr)
|
|
652
|
+
{
|
|
653
|
+
Napi::Error::New(env, "onSignalingStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
621
657
|
if (length < 1 || !info[0].IsFunction())
|
|
622
658
|
{
|
|
623
659
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -647,6 +683,12 @@ void PeerConnectionWrapper::onGatheringStateChange(const Napi::CallbackInfo &inf
|
|
|
647
683
|
Napi::Env env = info.Env();
|
|
648
684
|
int length = info.Length();
|
|
649
685
|
|
|
686
|
+
if (!mRtcPeerConnPtr)
|
|
687
|
+
{
|
|
688
|
+
Napi::Error::New(env, "onGatheringStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
650
692
|
if (length < 1 || !info[0].IsFunction())
|
|
651
693
|
{
|
|
652
694
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -676,6 +718,12 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
676
718
|
Napi::Env env = info.Env();
|
|
677
719
|
int length = info.Length();
|
|
678
720
|
|
|
721
|
+
if (!mRtcPeerConnPtr)
|
|
722
|
+
{
|
|
723
|
+
Napi::Error::New(env, "onDataChannel() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
|
|
679
727
|
if (length < 1 || !info[0].IsFunction())
|
|
680
728
|
{
|
|
681
729
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -704,6 +752,7 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
704
752
|
Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
705
753
|
{
|
|
706
754
|
Napi::Env env = info.Env();
|
|
755
|
+
|
|
707
756
|
if (!mRtcPeerConnPtr)
|
|
708
757
|
{
|
|
709
758
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -715,7 +764,7 @@ Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
|
715
764
|
}
|
|
716
765
|
catch (std::exception &ex)
|
|
717
766
|
{
|
|
718
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
767
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
719
768
|
return Napi::Number::New(info.Env(), 0);
|
|
720
769
|
}
|
|
721
770
|
}
|
|
@@ -723,6 +772,7 @@ Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
|
723
772
|
Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
724
773
|
{
|
|
725
774
|
Napi::Env env = info.Env();
|
|
775
|
+
|
|
726
776
|
if (!mRtcPeerConnPtr)
|
|
727
777
|
{
|
|
728
778
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -734,7 +784,7 @@ Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
|
734
784
|
}
|
|
735
785
|
catch (std::exception &ex)
|
|
736
786
|
{
|
|
737
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
787
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
738
788
|
return Napi::Number::New(info.Env(), 0);
|
|
739
789
|
}
|
|
740
790
|
}
|
|
@@ -742,6 +792,7 @@ Napi::Value PeerConnectionWrapper::bytesReceived(const Napi::CallbackInfo &info)
|
|
|
742
792
|
Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
743
793
|
{
|
|
744
794
|
Napi::Env env = info.Env();
|
|
795
|
+
|
|
745
796
|
if (!mRtcPeerConnPtr)
|
|
746
797
|
{
|
|
747
798
|
return Napi::Number::New(info.Env(), 0);
|
|
@@ -753,7 +804,7 @@ Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
|
753
804
|
}
|
|
754
805
|
catch (std::exception &ex)
|
|
755
806
|
{
|
|
756
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
807
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
757
808
|
return Napi::Number::New(info.Env(), -1);
|
|
758
809
|
}
|
|
759
810
|
}
|
|
@@ -761,16 +812,17 @@ Napi::Value PeerConnectionWrapper::rtt(const Napi::CallbackInfo &info)
|
|
|
761
812
|
Napi::Value PeerConnectionWrapper::getSelectedCandidatePair(const Napi::CallbackInfo &info)
|
|
762
813
|
{
|
|
763
814
|
Napi::Env env = info.Env();
|
|
815
|
+
|
|
764
816
|
if (!mRtcPeerConnPtr)
|
|
765
817
|
{
|
|
766
|
-
return
|
|
818
|
+
return env.Null();
|
|
767
819
|
}
|
|
768
820
|
|
|
769
821
|
try
|
|
770
822
|
{
|
|
771
823
|
rtc::Candidate local, remote;
|
|
772
824
|
if (!mRtcPeerConnPtr->getSelectedCandidatePair(&local, &remote))
|
|
773
|
-
return
|
|
825
|
+
return env.Null();
|
|
774
826
|
|
|
775
827
|
Napi::Object retvalue = Napi::Object::New(env);
|
|
776
828
|
Napi::Object localObj = Napi::Object::New(env);
|
|
@@ -793,7 +845,7 @@ Napi::Value PeerConnectionWrapper::getSelectedCandidatePair(const Napi::Callback
|
|
|
793
845
|
}
|
|
794
846
|
catch (std::exception &ex)
|
|
795
847
|
{
|
|
796
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
848
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
797
849
|
return Napi::Number::New(info.Env(), -1);
|
|
798
850
|
}
|
|
799
851
|
}
|
|
@@ -841,7 +893,7 @@ Napi::Value PeerConnectionWrapper::addTrack(const Napi::CallbackInfo &info)
|
|
|
841
893
|
|
|
842
894
|
if (!mRtcPeerConnPtr)
|
|
843
895
|
{
|
|
844
|
-
Napi::Error::New(
|
|
896
|
+
Napi::Error::New(env, "addTrack() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
845
897
|
return env.Null();
|
|
846
898
|
}
|
|
847
899
|
|
|
@@ -875,7 +927,7 @@ Napi::Value PeerConnectionWrapper::addTrack(const Napi::CallbackInfo &info)
|
|
|
875
927
|
}
|
|
876
928
|
catch (std::exception &ex)
|
|
877
929
|
{
|
|
878
|
-
Napi::Error::New(env, std::string("libdatachannel error
|
|
930
|
+
Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
|
|
879
931
|
return env.Null();
|
|
880
932
|
}
|
|
881
933
|
}
|
|
@@ -885,6 +937,12 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
885
937
|
Napi::Env env = info.Env();
|
|
886
938
|
int length = info.Length();
|
|
887
939
|
|
|
940
|
+
if (!mRtcPeerConnPtr)
|
|
941
|
+
{
|
|
942
|
+
Napi::Error::New(env, "onGatheringStateChange() called on destroyed peer connection").ThrowAsJavaScriptException();
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
|
|
888
946
|
if (length < 1 || !info[0].IsFunction())
|
|
889
947
|
{
|
|
890
948
|
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
@@ -894,8 +952,7 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
894
952
|
// Callback
|
|
895
953
|
mOnTrackCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
896
954
|
|
|
897
|
-
mRtcPeerConnPtr->onTrack([&](std::shared_ptr<rtc::Track> track)
|
|
898
|
-
{
|
|
955
|
+
mRtcPeerConnPtr->onTrack([&](std::shared_ptr<rtc::Track> track) {
|
|
899
956
|
if (mOnTrackCallback)
|
|
900
957
|
mOnTrackCallback->call([this, track](Napi::Env env, std::vector<napi_value> &args) {
|
|
901
958
|
// Check the peer connection is not closed
|
|
@@ -913,14 +970,14 @@ void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
|
913
970
|
Napi::Value PeerConnectionWrapper::hasMedia(const Napi::CallbackInfo &info)
|
|
914
971
|
{
|
|
915
972
|
Napi::Env env = info.Env();
|
|
916
|
-
return Napi::Boolean::New(env, mRtcPeerConnPtr->hasMedia());
|
|
973
|
+
return Napi::Boolean::New(env, mRtcPeerConnPtr ? mRtcPeerConnPtr->hasMedia() : false);
|
|
917
974
|
}
|
|
918
975
|
|
|
919
976
|
Napi::Value PeerConnectionWrapper::state(const Napi::CallbackInfo &info)
|
|
920
977
|
{
|
|
921
978
|
Napi::Env env = info.Env();
|
|
922
979
|
std::ostringstream stream;
|
|
923
|
-
stream << mRtcPeerConnPtr->state();
|
|
980
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->state() : rtc::PeerConnection::State::Closed);
|
|
924
981
|
return Napi::String::New(env, stream.str());
|
|
925
982
|
}
|
|
926
983
|
|
|
@@ -928,7 +985,7 @@ Napi::Value PeerConnectionWrapper::signalingState(const Napi::CallbackInfo &info
|
|
|
928
985
|
{
|
|
929
986
|
Napi::Env env = info.Env();
|
|
930
987
|
std::ostringstream stream;
|
|
931
|
-
stream << mRtcPeerConnPtr->signalingState();
|
|
988
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->signalingState() : rtc::PeerConnection::SignalingState::Stable);
|
|
932
989
|
return Napi::String::New(env, stream.str());
|
|
933
990
|
}
|
|
934
991
|
|
|
@@ -936,6 +993,6 @@ Napi::Value PeerConnectionWrapper::gatheringState(const Napi::CallbackInfo &info
|
|
|
936
993
|
{
|
|
937
994
|
Napi::Env env = info.Env();
|
|
938
995
|
std::ostringstream stream;
|
|
939
|
-
stream << mRtcPeerConnPtr->gatheringState();
|
|
996
|
+
stream << (mRtcPeerConnPtr ? mRtcPeerConnPtr->gatheringState() : rtc::PeerConnection::GatheringState::Complete);
|
|
940
997
|
return Napi::String::New(env, stream.str());
|
|
941
998
|
}
|
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,48 +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');
|
|
70
|
+
dc2.onClosed(() => {
|
|
71
|
+
console.log('dc2 closed');
|
|
72
|
+
});
|
|
69
73
|
});
|
|
70
74
|
|
|
71
75
|
// DataChannel Options
|
|
@@ -77,25 +81,22 @@ peer2.onDataChannel((dc) => {
|
|
|
77
81
|
// maxPacketLifeTime?: number;
|
|
78
82
|
// maxRetransmits?: number;
|
|
79
83
|
// }
|
|
80
|
-
dc1 = peer1.createDataChannel(
|
|
84
|
+
dc1 = peer1.createDataChannel('test');
|
|
81
85
|
dc1.onOpen(() => {
|
|
82
|
-
dc1.sendMessage(
|
|
86
|
+
dc1.sendMessage('Hello from Peer1');
|
|
83
87
|
// Binary message: Use sendMessageBinary(Buffer)
|
|
84
88
|
});
|
|
85
89
|
dc1.onMessage((msg) => {
|
|
86
90
|
console.log('Peer1 Received Msg:', msg);
|
|
87
91
|
});
|
|
92
|
+
dc1.onClosed(() => {
|
|
93
|
+
console.log('dc1 closed');
|
|
94
|
+
});
|
|
88
95
|
|
|
89
96
|
setTimeout(() => {
|
|
90
97
|
dc1.close();
|
|
91
98
|
dc2.close();
|
|
92
99
|
peer1.close();
|
|
93
100
|
peer2.close();
|
|
94
|
-
dc1 = null;
|
|
95
|
-
dc2 = null;
|
|
96
|
-
peer1 = null;
|
|
97
|
-
peer2 = null;
|
|
98
101
|
nodeDataChannel.cleanup();
|
|
99
|
-
// No need for this (>= V0.1.14)
|
|
100
|
-
// process.exit();
|
|
101
102
|
}, 5 * 1000);
|