node-datachannel 0.1.13 → 0.2.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-datachannel",
3
- "version": "0.1.13",
3
+ "version": "0.2.1",
4
4
  "description": "libdatachannel node bindings",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -15,17 +15,31 @@
15
15
  "build": "cmake-js build",
16
16
  "_prebuild": "prebuild --backend cmake-js",
17
17
  "clean": "cmake-js clean",
18
- "test": "jest --forceExit"
18
+ "test": "jest"
19
19
  },
20
20
  "repository": {
21
21
  "type": "git",
22
22
  "url": "git+https://github.com/murat-dogan/node-datachannel.git"
23
23
  },
24
24
  "keywords": [
25
- "libdatachannel"
25
+ "libdatachannel",
26
+ "webrtc",
27
+ "p2p",
28
+ "peer-to-peer",
29
+ "datachannel",
30
+ "data channel"
26
31
  ],
27
- "author": "Murat Doğan",
28
- "license": "GPL-2.0-or-later",
32
+ "contributors": [
33
+ {
34
+ "name": "Murat Doğan",
35
+ "url": "https://github.com/murat-dogan"
36
+ },
37
+ {
38
+ "name": "Paul-Louis Ageneau",
39
+ "url": "https://github.com/paullouisageneau"
40
+ }
41
+ ],
42
+ "license": "LGPL",
29
43
  "gypfile": true,
30
44
  "bugs": {
31
45
  "url": "https://github.com/murat-dogan/node-datachannel/issues"
@@ -35,8 +49,8 @@
35
49
  "cmake-js": "^6.2.1",
36
50
  "jest": "^27.2.5",
37
51
  "nan": "^2.15.0",
38
- "napi-thread-safe-callback": "0.0.6",
39
- "node-addon-api": "^3.2.1",
52
+ "napi-thread-safe-callback-cancellable": "^0.0.7",
53
+ "node-addon-api": "^4.2.0",
40
54
  "prebuild": "^11.0.0"
41
55
  },
42
56
  "bundledDependencies": [
@@ -1,6 +1,14 @@
1
1
  #include "data-channel-wrapper.h"
2
2
 
3
3
  Napi::FunctionReference DataChannelWrapper::constructor;
4
+ std::unordered_set<DataChannelWrapper *> DataChannelWrapper::instances;
5
+
6
+ void DataChannelWrapper::CloseAll()
7
+ {
8
+ auto copy(instances);
9
+ for (auto inst : copy)
10
+ inst->doClose();
11
+ }
4
12
 
5
13
  Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
6
14
  {
@@ -9,21 +17,21 @@ Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
9
17
  Napi::Function func = DefineClass(
10
18
  env,
11
19
  "DataChannel",
12
- {InstanceMethod("close", &DataChannelWrapper::close),
13
- InstanceMethod("getLabel", &DataChannelWrapper::getLabel),
14
- InstanceMethod("sendMessage", &DataChannelWrapper::sendMessage),
15
- InstanceMethod("sendMessageBinary", &DataChannelWrapper::sendMessageBinary),
16
- InstanceMethod("isOpen", &DataChannelWrapper::isOpen),
17
- InstanceMethod("availableAmount", &DataChannelWrapper::availableAmount),
18
- InstanceMethod("bufferedAmount", &DataChannelWrapper::bufferedAmount),
19
- InstanceMethod("maxMessageSize", &DataChannelWrapper::maxMessageSize),
20
- InstanceMethod("setBufferedAmountLowThreshold", &DataChannelWrapper::setBufferedAmountLowThreshold),
21
- InstanceMethod("onOpen", &DataChannelWrapper::onOpen),
22
- InstanceMethod("onClosed", &DataChannelWrapper::onClosed),
23
- InstanceMethod("onError", &DataChannelWrapper::onError),
24
- InstanceMethod("onAvailable", &DataChannelWrapper::onAvailable),
25
- InstanceMethod("onBufferedAmountLow", &DataChannelWrapper::onBufferedAmountLow),
26
- InstanceMethod("onMessage", &DataChannelWrapper::onMessage)});
20
+ {
21
+ InstanceMethod("close", &DataChannelWrapper::close),
22
+ InstanceMethod("getLabel", &DataChannelWrapper::getLabel),
23
+ InstanceMethod("sendMessage", &DataChannelWrapper::sendMessage),
24
+ InstanceMethod("sendMessageBinary", &DataChannelWrapper::sendMessageBinary),
25
+ InstanceMethod("isOpen", &DataChannelWrapper::isOpen),
26
+ InstanceMethod("bufferedAmount", &DataChannelWrapper::bufferedAmount),
27
+ InstanceMethod("maxMessageSize", &DataChannelWrapper::maxMessageSize),
28
+ InstanceMethod("setBufferedAmountLowThreshold", &DataChannelWrapper::setBufferedAmountLowThreshold),
29
+ InstanceMethod("onOpen", &DataChannelWrapper::onOpen),
30
+ InstanceMethod("onClosed", &DataChannelWrapper::onClosed),
31
+ InstanceMethod("onError", &DataChannelWrapper::onError),
32
+ InstanceMethod("onBufferedAmountLow", &DataChannelWrapper::onBufferedAmountLow),
33
+ InstanceMethod("onMessage", &DataChannelWrapper::onMessage),
34
+ });
27
35
 
28
36
  constructor = Napi::Persistent(func);
29
37
  constructor.SuppressDestruct();
@@ -35,14 +43,29 @@ Napi::Object DataChannelWrapper::Init(Napi::Env env, Napi::Object exports)
35
43
  DataChannelWrapper::DataChannelWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<DataChannelWrapper>(info)
36
44
  {
37
45
  mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
46
+
47
+ instances.insert(this);
38
48
  }
39
49
 
40
50
  DataChannelWrapper::~DataChannelWrapper()
41
51
  {
52
+ doClose();
53
+ }
54
+
55
+ void DataChannelWrapper::doClose()
56
+ {
57
+ instances.erase(this);
58
+
42
59
  if (mDataChannelPtr)
43
60
  {
44
61
  try
45
62
  {
63
+ mOnOpenCallback.reset();
64
+ mOnClosedCallback.reset();
65
+ mOnErrorCallback.reset();
66
+ mOnBufferedAmountLowCallback.reset();
67
+ mOnMessageCallback.reset();
68
+
46
69
  mDataChannelPtr->close();
47
70
  mDataChannelPtr.reset();
48
71
  }
@@ -56,23 +79,7 @@ DataChannelWrapper::~DataChannelWrapper()
56
79
 
57
80
  void DataChannelWrapper::close(const Napi::CallbackInfo &info)
58
81
  {
59
- Napi::Env env = info.Env();
60
- if (!mDataChannelPtr)
61
- {
62
- Napi::Error::New(env, "It seems data-channel is destroyed!").ThrowAsJavaScriptException();
63
- return;
64
- }
65
-
66
- try
67
- {
68
- mDataChannelPtr->close();
69
- mDataChannelPtr.reset();
70
- }
71
- catch (std::exception &ex)
72
- {
73
- Napi::Error::New(env, std::string("libdatachannel error while closing dataChannel# ") + ex.what()).ThrowAsJavaScriptException();
74
- return;
75
- }
82
+ doClose();
76
83
  }
77
84
 
78
85
  Napi::Value DataChannelWrapper::getLabel(const Napi::CallbackInfo &info)
@@ -163,25 +170,6 @@ Napi::Value DataChannelWrapper::isOpen(const Napi::CallbackInfo &info)
163
170
  }
164
171
  }
165
172
 
166
- Napi::Value DataChannelWrapper::availableAmount(const Napi::CallbackInfo &info)
167
- {
168
- Napi::Env env = info.Env();
169
- if (!mDataChannelPtr)
170
- {
171
- return Napi::Number::New(info.Env(), 0);
172
- }
173
-
174
- try
175
- {
176
- return Napi::Number::New(info.Env(), mDataChannelPtr->availableAmount());
177
- }
178
- catch (std::exception &ex)
179
- {
180
- Napi::Error::New(env, std::string("libdatachannel error# ") + ex.what()).ThrowAsJavaScriptException();
181
- return Napi::Number::New(info.Env(), 0);
182
- }
183
- }
184
-
185
173
  Napi::Value DataChannelWrapper::bufferedAmount(const Napi::CallbackInfo &info)
186
174
  {
187
175
  Napi::Env env = info.Env();
@@ -260,16 +248,20 @@ void DataChannelWrapper::onOpen(const Napi::CallbackInfo &info)
260
248
  }
261
249
 
262
250
  // Callback
263
- mOnOpenCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
251
+ mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
264
252
 
265
- mDataChannelPtr->onOpen([&]() {
253
+ mDataChannelPtr->onOpen([&]()
254
+ {
266
255
  if (mOnOpenCallback)
267
- mOnOpenCallback->call([](Napi::Env env, std::vector<napi_value> &args) {
256
+ mOnOpenCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
257
+ // Check the peer connection is not closed
258
+ if(instances.find(this) == instances.end())
259
+ throw ThreadSafeCallback::CancelException();
260
+
268
261
  // This will run in main thread and needs to construct the
269
262
  // arguments for the call
270
263
  args = {};
271
- });
272
- });
264
+ }); });
273
265
  }
274
266
 
275
267
  void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
@@ -284,16 +276,20 @@ void DataChannelWrapper::onClosed(const Napi::CallbackInfo &info)
284
276
  }
285
277
 
286
278
  // Callback
287
- mOnClosedCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
279
+ mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
288
280
 
289
- mDataChannelPtr->onClosed([&]() {
281
+ mDataChannelPtr->onClosed([&]()
282
+ {
290
283
  if (mOnClosedCallback)
291
- mOnClosedCallback->call([](Napi::Env env, std::vector<napi_value> &args) {
284
+ mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
285
+ // Check the peer connection is not closed
286
+ if(instances.find(this) == instances.end())
287
+ throw ThreadSafeCallback::CancelException();
288
+
292
289
  // This will run in main thread and needs to construct the
293
290
  // arguments for the call
294
291
  args = {};
295
- });
296
- });
292
+ }); });
297
293
  }
298
294
 
299
295
  void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
@@ -308,40 +304,20 @@ void DataChannelWrapper::onError(const Napi::CallbackInfo &info)
308
304
  }
309
305
 
310
306
  // Callback
311
- mOnErrorCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
307
+ mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
312
308
 
313
- mDataChannelPtr->onError([&](const std::string &error) {
309
+ mDataChannelPtr->onError([&](const std::string &error)
310
+ {
314
311
  if (mOnErrorCallback)
315
- mOnErrorCallback->call([error](Napi::Env env, std::vector<napi_value> &args) {
316
- // This will run in main thread and needs to construct the
317
- // arguments for the call
318
- args = {Napi::String::New(env, error)};
319
- });
320
- });
321
- }
312
+ mOnErrorCallback->call([this, error](Napi::Env env, std::vector<napi_value> &args) {
313
+ // Check the peer connection is not closed
314
+ if(instances.find(this) == instances.end())
315
+ throw ThreadSafeCallback::CancelException();
322
316
 
323
- void DataChannelWrapper::onAvailable(const Napi::CallbackInfo &info)
324
- {
325
- Napi::Env env = info.Env();
326
- int length = info.Length();
327
-
328
- if (length < 1 || !info[0].IsFunction())
329
- {
330
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
331
- return;
332
- }
333
-
334
- // Callback
335
- mOnAvailableCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
336
-
337
- mDataChannelPtr->onAvailable([&]() {
338
- if (mOnAvailableCallback)
339
- mOnAvailableCallback->call([](Napi::Env env, std::vector<napi_value> &args) {
340
317
  // This will run in main thread and needs to construct the
341
318
  // arguments for the call
342
- args = {};
343
- });
344
- });
319
+ args = {Napi::String::New(env, error)};
320
+ }); });
345
321
  }
346
322
 
347
323
  void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
@@ -356,16 +332,20 @@ void DataChannelWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
356
332
  }
357
333
 
358
334
  // Callback
359
- mOnBufferedAmountLowCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
335
+ mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
360
336
 
361
- mDataChannelPtr->onBufferedAmountLow([&]() {
337
+ mDataChannelPtr->onBufferedAmountLow([&]()
338
+ {
362
339
  if (mOnBufferedAmountLowCallback)
363
- mOnBufferedAmountLowCallback->call([](Napi::Env env, std::vector<napi_value> &args) {
340
+ mOnBufferedAmountLowCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
341
+ // Check the peer connection is not closed
342
+ if(instances.find(this) == instances.end())
343
+ throw ThreadSafeCallback::CancelException();
344
+
364
345
  // This will run in main thread and needs to construct the
365
346
  // arguments for the call
366
347
  args = {};
367
- });
368
- });
348
+ }); });
369
349
  }
370
350
 
371
351
  void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
@@ -380,11 +360,16 @@ void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
380
360
  }
381
361
 
382
362
  // Callback
383
- mOnMessageCallback = std::make_shared<ThreadSafeCallback>(info[0].As<Napi::Function>());
363
+ mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
384
364
 
385
- mDataChannelPtr->onMessage([&](const std::variant<rtc::binary, std::string> &message) {
365
+ mDataChannelPtr->onMessage([&](const std::variant<rtc::binary, std::string> &message)
366
+ {
386
367
  if (mOnMessageCallback)
387
- mOnMessageCallback->call([message](Napi::Env env, std::vector<napi_value> &args) {
368
+ mOnMessageCallback->call([this, message](Napi::Env env, std::vector<napi_value> &args) {
369
+ // Check the peer connection is not closed
370
+ if(instances.find(this) == instances.end())
371
+ throw ThreadSafeCallback::CancelException();
372
+
388
373
  // This will run in main thread and needs to construct the
389
374
  // arguments for the call
390
375
  Napi::Object payload = Napi::Object::New(env);
@@ -396,6 +381,5 @@ void DataChannelWrapper::onMessage(const Napi::CallbackInfo &info)
396
381
  {
397
382
  args = {Napi::Buffer<std::byte>::Copy(env, std::get<rtc::binary>(message).data(), std::get<rtc::binary>(message).size())};
398
383
  }
399
- });
400
- });
401
- }
384
+ }); });
385
+ }
@@ -5,9 +5,12 @@
5
5
  #include <string>
6
6
  #include <variant>
7
7
  #include <memory>
8
+ #include <unordered_set>
9
+
8
10
  #include <napi.h>
9
- #include <napi-thread-safe-callback.hpp>
10
- #include "rtc/rtc.hpp"
11
+ #include <rtc/rtc.hpp>
12
+
13
+ #include "thread-safe-callback.h"
11
14
 
12
15
  class DataChannelWrapper : public Napi::ObjectWrap<DataChannelWrapper>
13
16
  {
@@ -23,7 +26,6 @@ public:
23
26
  Napi::Value sendMessage(const Napi::CallbackInfo &info);
24
27
  Napi::Value sendMessageBinary(const Napi::CallbackInfo &info);
25
28
  Napi::Value isOpen(const Napi::CallbackInfo &info);
26
- Napi::Value availableAmount(const Napi::CallbackInfo &info);
27
29
  Napi::Value bufferedAmount(const Napi::CallbackInfo &info);
28
30
  Napi::Value maxMessageSize(const Napi::CallbackInfo &info);
29
31
  void setBufferedAmountLowThreshold(const Napi::CallbackInfo &info);
@@ -32,21 +34,26 @@ public:
32
34
  void onOpen(const Napi::CallbackInfo &info);
33
35
  void onClosed(const Napi::CallbackInfo &info);
34
36
  void onError(const Napi::CallbackInfo &info);
35
- void onAvailable(const Napi::CallbackInfo &info);
36
37
  void onBufferedAmountLow(const Napi::CallbackInfo &info);
37
38
  void onMessage(const Napi::CallbackInfo &info);
38
39
 
40
+ // Close all existing DataChannels
41
+ static void CloseAll();
42
+
39
43
  private:
44
+ static std::unordered_set<DataChannelWrapper*> instances;
45
+
46
+ void doClose();
47
+
40
48
  std::string mLabel;
41
49
  std::shared_ptr<rtc::DataChannel> mDataChannelPtr = nullptr;
42
50
 
43
51
  // Callback Ptrs
44
- std::shared_ptr<ThreadSafeCallback> mOnOpenCallback = nullptr;
45
- std::shared_ptr<ThreadSafeCallback> mOnClosedCallback = nullptr;
46
- std::shared_ptr<ThreadSafeCallback> mOnErrorCallback = nullptr;
47
- std::shared_ptr<ThreadSafeCallback> mOnAvailableCallback = nullptr;
48
- std::shared_ptr<ThreadSafeCallback> mOnBufferedAmountLowCallback = nullptr;
49
- std::shared_ptr<ThreadSafeCallback> mOnMessageCallback = nullptr;
52
+ std::unique_ptr<ThreadSafeCallback> mOnOpenCallback = nullptr;
53
+ std::unique_ptr<ThreadSafeCallback> mOnClosedCallback = nullptr;
54
+ std::unique_ptr<ThreadSafeCallback> mOnErrorCallback = nullptr;
55
+ std::unique_ptr<ThreadSafeCallback> mOnBufferedAmountLowCallback = nullptr;
56
+ std::unique_ptr<ThreadSafeCallback> mOnMessageCallback = nullptr;
50
57
  };
51
58
 
52
- #endif // DATA_CHANNEL_WRAPPER_H
59
+ #endif // DATA_CHANNEL_WRAPPER_H
package/src/main.cpp CHANGED
@@ -2,10 +2,18 @@
2
2
  #include "rtc-wrapper.h"
3
3
  #include "peer-connection-wrapper.h"
4
4
  #include "data-channel-wrapper.h"
5
+ #include "media-rtcpreceivingsession-wrapper.h"
6
+ #include "media-track-wrapper.h"
7
+ #include "media-video-wrapper.h"
8
+ #include "media-audio-wrapper.h"
5
9
 
6
10
  Napi::Object InitAll(Napi::Env env, Napi::Object exports)
7
11
  {
8
12
  RtcWrapper::Init(env, exports);
13
+ RtcpReceivingSessionWrapper::Init(env,exports);
14
+ TrackWrapper::Init(env,exports);
15
+ VideoWrapper::Init(env,exports);
16
+ AudioWrapper::Init(env,exports);
9
17
  DataChannelWrapper::Init(env, exports);
10
18
  PeerConnectionWrapper::Init(env, exports);
11
19
  return exports;