node-datachannel 0.3.6 → 0.4.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/.github/workflows/build-linux-arm64-test.yml +1 -1
- package/.github/workflows/build-linux.yml +3 -3
- package/.github/workflows/build-mac-m1.yml +1 -1
- package/.github/workflows/build-mac-x64.yml +1 -1
- package/.github/workflows/build-win.yml +3 -3
- package/API.md +5 -0
- package/CMakeLists.txt +13 -15
- package/LICENSE +373 -504
- package/README.md +1 -0
- package/lib/index.d.ts +4 -1
- package/package.json +3 -2
- package/src/data-channel-wrapper.cpp +1 -1
- package/src/peer-connection-wrapper.cpp +30 -5
- package/src/peer-connection-wrapper.h +8 -1
- package/src/rtc-wrapper.cpp +42 -2
- package/src/rtc-wrapper.h +4 -0
- package/test/connectivity.js +1 -0
package/README.md
CHANGED
|
@@ -30,6 +30,7 @@ npm install node-datachannel
|
|
|
30
30
|
| Node V15 | + | + | + | + | + | + |
|
|
31
31
|
| Node V16 | + | + | + | + | + | + |
|
|
32
32
|
| Node V17 | + | + | + | + | + | + |
|
|
33
|
+
| Node V18 | + | + | + | + | + | + |
|
|
33
34
|
|
|
34
35
|
1) Please note that; For Linux-arm64 platform we need OpenSSL to be installed locally.
|
|
35
36
|
|
package/lib/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface SctpSettings {
|
|
|
17
17
|
|
|
18
18
|
// Functions
|
|
19
19
|
export function preload(): void;
|
|
20
|
-
export function initLogger(level: LogLevel): void;
|
|
20
|
+
export function initLogger(level: LogLevel, callback?: (level: LogLevel, message: string) => void): void;
|
|
21
21
|
export function cleanup(): void;
|
|
22
22
|
export function setSctpSettings(settings: SctpSettings): void;
|
|
23
23
|
|
|
@@ -46,9 +46,11 @@ export interface IceServer {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
export type TransportPolicy = 'all' | 'relay';
|
|
49
|
+
|
|
49
50
|
export interface RtcConfig {
|
|
50
51
|
iceServers: (string | IceServer)[];
|
|
51
52
|
proxyServer?: ProxyServer;
|
|
53
|
+
bindAddress?: string;
|
|
52
54
|
enableIceTcp?: boolean;
|
|
53
55
|
enableIceUdpMux?: boolean;
|
|
54
56
|
disableAutoNegotiation?: boolean;
|
|
@@ -204,6 +206,7 @@ export class DataChannel {
|
|
|
204
206
|
export class PeerConnection {
|
|
205
207
|
constructor(peerName: string, config: RtcConfig);
|
|
206
208
|
close(): void;
|
|
209
|
+
destroy(): void;
|
|
207
210
|
setLocalDescription(type?: DescriptionType): void;
|
|
208
211
|
setRemoteDescription(sdp: string, type: DescriptionType): void;
|
|
209
212
|
localDescription(): { type: string; sdp: string } | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-datachannel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "libdatachannel node bindings",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"install": "prebuild-install || (npm install --ignore-scripts && npm run _prebuild)",
|
|
14
14
|
"install-nice": "npm run clean && cmake-js build --CDUSE_NICE=1",
|
|
15
15
|
"build": "cmake-js build",
|
|
16
|
+
"build:debug": "cmake-js build -D",
|
|
16
17
|
"_prebuild": "prebuild --backend cmake-js",
|
|
17
18
|
"clean": "cmake-js clean",
|
|
18
19
|
"lint": "eslint lib/**/* test/**/*",
|
|
@@ -40,7 +41,7 @@
|
|
|
40
41
|
"url": "https://github.com/paullouisageneau"
|
|
41
42
|
}
|
|
42
43
|
],
|
|
43
|
-
"license": "
|
|
44
|
+
"license": "MPL 2.0",
|
|
44
45
|
"gypfile": true,
|
|
45
46
|
"bugs": {
|
|
46
47
|
"url": "https://github.com/murat-dogan/node-datachannel/issues"
|
|
@@ -103,7 +103,7 @@ Napi::Value DataChannelWrapper::getId(const Napi::CallbackInfo &info)
|
|
|
103
103
|
return info.Env().Null();
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
return Napi::Number::New(info.Env(), mDataChannelPtr->id());
|
|
106
|
+
return Napi::Number::New(info.Env(), mDataChannelPtr->id().value_or(-1));
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
Napi::Value DataChannelWrapper::getProtocol(const Napi::CallbackInfo &info)
|
|
@@ -17,6 +17,13 @@ void PeerConnectionWrapper::CloseAll()
|
|
|
17
17
|
inst->doClose();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
void PeerConnectionWrapper::ResetCallbacksAll()
|
|
21
|
+
{
|
|
22
|
+
auto copy(instances);
|
|
23
|
+
for (auto inst : copy)
|
|
24
|
+
inst->doResetCallbacks();
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
Napi::Object PeerConnectionWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
21
28
|
{
|
|
22
29
|
Napi::HandleScope scope(env);
|
|
@@ -26,6 +33,7 @@ Napi::Object PeerConnectionWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
26
33
|
"PeerConnection",
|
|
27
34
|
{
|
|
28
35
|
InstanceMethod("close", &PeerConnectionWrapper::close),
|
|
36
|
+
InstanceMethod("destroy", &PeerConnectionWrapper::destroy),
|
|
29
37
|
InstanceMethod("setLocalDescription", &PeerConnectionWrapper::setLocalDescription),
|
|
30
38
|
InstanceMethod("setRemoteDescription", &PeerConnectionWrapper::setRemoteDescription),
|
|
31
39
|
InstanceMethod("localDescription", &PeerConnectionWrapper::localDescription),
|
|
@@ -163,6 +171,10 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
163
171
|
rtcConfig.proxyServer = rtc::ProxyServer(type, ip, port, username, password);
|
|
164
172
|
}
|
|
165
173
|
|
|
174
|
+
// bind address, libjuice only
|
|
175
|
+
if(config.Get("bindAddress").IsString())
|
|
176
|
+
rtcConfig.bindAddress = config.Get("bindAddress").As<Napi::String>().ToString();
|
|
177
|
+
|
|
166
178
|
// Port Ranges
|
|
167
179
|
if (config.Get("portRangeBegin").IsNumber())
|
|
168
180
|
rtcConfig.portRangeBegin = config.Get("portRangeBegin").As<Napi::Number>().Uint32Value();
|
|
@@ -225,7 +237,7 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
225
237
|
|
|
226
238
|
PeerConnectionWrapper::~PeerConnectionWrapper()
|
|
227
239
|
{
|
|
228
|
-
|
|
240
|
+
doDestroy();
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
void PeerConnectionWrapper::doClose()
|
|
@@ -243,7 +255,21 @@ void PeerConnectionWrapper::doClose()
|
|
|
243
255
|
return;
|
|
244
256
|
}
|
|
245
257
|
}
|
|
258
|
+
}
|
|
246
259
|
|
|
260
|
+
void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
261
|
+
{
|
|
262
|
+
doClose();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
void PeerConnectionWrapper::doDestroy()
|
|
266
|
+
{
|
|
267
|
+
doClose();
|
|
268
|
+
doResetCallbacks();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
void PeerConnectionWrapper::doResetCallbacks()
|
|
272
|
+
{
|
|
247
273
|
mOnLocalDescriptionCallback.reset();
|
|
248
274
|
mOnLocalCandidateCallback.reset();
|
|
249
275
|
mOnStateChangeCallback.reset();
|
|
@@ -254,9 +280,9 @@ void PeerConnectionWrapper::doClose()
|
|
|
254
280
|
instances.erase(this);
|
|
255
281
|
}
|
|
256
282
|
|
|
257
|
-
void PeerConnectionWrapper::
|
|
283
|
+
void PeerConnectionWrapper::destroy(const Napi::CallbackInfo &info)
|
|
258
284
|
{
|
|
259
|
-
|
|
285
|
+
doDestroy();
|
|
260
286
|
}
|
|
261
287
|
|
|
262
288
|
void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
@@ -640,8 +666,7 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
640
666
|
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state) {
|
|
641
667
|
if (mOnStateChangeCallback)
|
|
642
668
|
mOnStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
643
|
-
|
|
644
|
-
if(state != rtc::PeerConnection::State::Closed && instances.find(this) == instances.end())
|
|
669
|
+
if(instances.find(this) == instances.end())
|
|
645
670
|
throw ThreadSafeCallback::CancelException();
|
|
646
671
|
|
|
647
672
|
// This will run in main thread and needs to construct the
|
|
@@ -19,6 +19,8 @@ public:
|
|
|
19
19
|
PeerConnectionWrapper(const Napi::CallbackInfo &info);
|
|
20
20
|
~PeerConnectionWrapper();
|
|
21
21
|
|
|
22
|
+
void destroy(const Napi::CallbackInfo &info);
|
|
23
|
+
|
|
22
24
|
// Functions
|
|
23
25
|
void close(const Napi::CallbackInfo &info);
|
|
24
26
|
void setLocalDescription(const Napi::CallbackInfo &info);
|
|
@@ -47,14 +49,19 @@ public:
|
|
|
47
49
|
Napi::Value rtt(const Napi::CallbackInfo &info);
|
|
48
50
|
Napi::Value getSelectedCandidatePair(const Napi::CallbackInfo &info);
|
|
49
51
|
|
|
50
|
-
// Close all existing
|
|
52
|
+
// Close all existing Peer Connections
|
|
51
53
|
static void CloseAll();
|
|
52
54
|
|
|
55
|
+
// Reset all Callbacks for existing Peer Connections
|
|
56
|
+
static void ResetCallbacksAll();
|
|
57
|
+
|
|
53
58
|
private:
|
|
54
59
|
static Napi::FunctionReference constructor;
|
|
55
60
|
static std::unordered_set<PeerConnectionWrapper *> instances;
|
|
56
61
|
|
|
57
62
|
void doClose();
|
|
63
|
+
void doDestroy();
|
|
64
|
+
void doResetCallbacks();
|
|
58
65
|
|
|
59
66
|
std::string mPeerName;
|
|
60
67
|
std::unique_ptr<rtc::PeerConnection> mRtcPeerConnPtr = nullptr;
|
package/src/rtc-wrapper.cpp
CHANGED
|
@@ -61,7 +61,42 @@ void RtcWrapper::initLogger(const Napi::CallbackInfo &info)
|
|
|
61
61
|
|
|
62
62
|
try
|
|
63
63
|
{
|
|
64
|
-
|
|
64
|
+
if (length < 2)
|
|
65
|
+
{
|
|
66
|
+
rtc::InitLogger(logLevel);
|
|
67
|
+
}
|
|
68
|
+
else
|
|
69
|
+
{
|
|
70
|
+
if (!info[1].IsFunction())
|
|
71
|
+
{
|
|
72
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
logCallback = std::make_unique<ThreadSafeCallback>(info[1].As<Napi::Function>());
|
|
76
|
+
rtc::InitLogger(logLevel, [&](rtc::LogLevel level, std::string message) {
|
|
77
|
+
if (logCallback)
|
|
78
|
+
logCallback->call([level, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args) {
|
|
79
|
+
// This will run in main thread and needs to construct the
|
|
80
|
+
// arguments for the call
|
|
81
|
+
|
|
82
|
+
std::string logLevel;
|
|
83
|
+
if (level == rtc::LogLevel::Verbose)
|
|
84
|
+
logLevel = "Verbose";
|
|
85
|
+
if (level == rtc::LogLevel::Debug)
|
|
86
|
+
logLevel = "Debug";
|
|
87
|
+
if (level == rtc::LogLevel::Info)
|
|
88
|
+
logLevel = "Info";
|
|
89
|
+
if (level == rtc::LogLevel::Warning)
|
|
90
|
+
logLevel = "Warning";
|
|
91
|
+
if (level == rtc::LogLevel::Error)
|
|
92
|
+
logLevel = "Error";
|
|
93
|
+
if (level == rtc::LogLevel::Fatal)
|
|
94
|
+
logLevel = "Fatal";
|
|
95
|
+
args = {Napi::String::New(env, logLevel), Napi::String::New(env, message)};
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
65
100
|
}
|
|
66
101
|
catch (std::exception &ex)
|
|
67
102
|
{
|
|
@@ -82,7 +117,12 @@ void RtcWrapper::cleanup(const Napi::CallbackInfo &info)
|
|
|
82
117
|
const auto timeout = std::chrono::seconds(10);
|
|
83
118
|
if(rtc::Cleanup().wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout)
|
|
84
119
|
throw std::runtime_error("cleanup timeout (possible deadlock)");
|
|
85
|
-
|
|
120
|
+
|
|
121
|
+
// Clear Callbacks
|
|
122
|
+
PeerConnectionWrapper::ResetCallbacksAll();
|
|
123
|
+
|
|
124
|
+
if (logCallback) logCallback.reset();
|
|
125
|
+
}
|
|
86
126
|
catch (std::exception &ex)
|
|
87
127
|
{
|
|
88
128
|
Napi::Error::New(env, std::string("libdatachannel error# ") + ex.what()).ThrowAsJavaScriptException();
|
package/src/rtc-wrapper.h
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
#include "rtc/rtc.hpp"
|
|
10
10
|
|
|
11
|
+
#include "thread-safe-callback.h"
|
|
12
|
+
|
|
11
13
|
class RtcWrapper
|
|
12
14
|
{
|
|
13
15
|
public:
|
|
@@ -16,6 +18,8 @@ public:
|
|
|
16
18
|
static void initLogger(const Napi::CallbackInfo &info);
|
|
17
19
|
static void cleanup(const Napi::CallbackInfo &info);
|
|
18
20
|
static void setSctpSettings(const Napi::CallbackInfo &info);
|
|
21
|
+
private:
|
|
22
|
+
static inline std::unique_ptr<ThreadSafeCallback> logCallback = nullptr;
|
|
19
23
|
};
|
|
20
24
|
|
|
21
25
|
#endif // RTC_WRAPPER_H
|
package/test/connectivity.js
CHANGED