node-datachannel 0.29.0 → 0.30.0

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.
Files changed (33) hide show
  1. package/.clang-format +17 -0
  2. package/CMakeLists.txt +5 -1
  3. package/dist/cjs/polyfill/RTCPeerConnection.cjs +6 -1
  4. package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
  5. package/dist/esm/polyfill/RTCPeerConnection.mjs +6 -1
  6. package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
  7. package/dist/types/polyfill/RTCPeerConnection.d.ts +1 -2
  8. package/package.json +3 -2
  9. package/src/cpp/data-channel-wrapper.cpp +432 -411
  10. package/src/cpp/data-channel-wrapper.h +0 -2
  11. package/src/cpp/ice-udp-mux-listener-wrapper.cpp +104 -97
  12. package/src/cpp/main.cpp +11 -11
  13. package/src/cpp/media-audio-wrapper.cpp +291 -294
  14. package/src/cpp/media-audio-wrapper.h +1 -3
  15. package/src/cpp/media-direction.cpp +32 -32
  16. package/src/cpp/media-direction.h +1 -1
  17. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +24 -28
  18. package/src/cpp/media-rtcpreceivingsession-wrapper.h +0 -5
  19. package/src/cpp/media-track-wrapper.cpp +350 -339
  20. package/src/cpp/media-track-wrapper.h +0 -3
  21. package/src/cpp/media-video-wrapper.cpp +312 -313
  22. package/src/cpp/media-video-wrapper.h +1 -3
  23. package/src/cpp/peer-connection-wrapper.cpp +1094 -1047
  24. package/src/cpp/peer-connection-wrapper.h +0 -2
  25. package/src/cpp/rtc-wrapper.cpp +142 -138
  26. package/src/cpp/rtc-wrapper.h +8 -10
  27. package/src/cpp/thread-safe-callback.cpp +39 -50
  28. package/src/cpp/thread-safe-callback.h +26 -28
  29. package/src/cpp/web-socket-server-wrapper.cpp +205 -199
  30. package/src/cpp/web-socket-server-wrapper.h +0 -4
  31. package/src/cpp/web-socket-wrapper.cpp +625 -598
  32. package/src/cpp/web-socket-wrapper.h +0 -3
  33. package/src/polyfill/RTCPeerConnection.ts +9 -3
@@ -7,763 +7,790 @@ std::unordered_set<WebSocketWrapper *> WebSocketWrapper::instances;
7
7
 
8
8
  void WebSocketWrapper::CloseAll()
9
9
  {
10
- PLOG_DEBUG << "CloseAll() called";
11
- auto copy(instances);
12
- for (auto inst : copy)
13
- inst->doClose();
10
+ PLOG_DEBUG << "CloseAll() called";
11
+ auto copy(instances);
12
+ for (auto inst : copy)
13
+ inst->doClose();
14
14
  }
15
15
 
16
16
  void WebSocketWrapper::CleanupAll()
17
17
  {
18
- PLOG_DEBUG << "CleanupAll() called";
19
- auto copy(instances);
20
- for (auto inst : copy)
21
- inst->doCleanup();
18
+ PLOG_DEBUG << "CleanupAll() called";
19
+ auto copy(instances);
20
+ for (auto inst : copy)
21
+ inst->doCleanup();
22
22
  }
23
23
 
24
24
  Napi::Object WebSocketWrapper::Init(Napi::Env env, Napi::Object exports)
25
25
  {
26
- Napi::HandleScope scope(env);
27
-
28
- Napi::Function func = DefineClass(
29
- env,
30
- "WebSocket",
31
- {
32
- InstanceMethod("open", &WebSocketWrapper::open),
33
- InstanceMethod("close", &WebSocketWrapper::close),
34
- InstanceMethod("forceClose", &WebSocketWrapper::forceClose),
35
- InstanceMethod("sendMessage", &WebSocketWrapper::sendMessage),
36
- InstanceMethod("sendMessageBinary", &WebSocketWrapper::sendMessageBinary),
37
- InstanceMethod("isOpen", &WebSocketWrapper::isOpen),
38
- InstanceMethod("bufferedAmount", &WebSocketWrapper::bufferedAmount),
39
- InstanceMethod("maxMessageSize", &WebSocketWrapper::maxMessageSize),
40
- InstanceMethod("setBufferedAmountLowThreshold", &WebSocketWrapper::setBufferedAmountLowThreshold),
41
- InstanceMethod("onOpen", &WebSocketWrapper::onOpen),
42
- InstanceMethod("onClosed", &WebSocketWrapper::onClosed),
43
- InstanceMethod("onError", &WebSocketWrapper::onError),
44
- InstanceMethod("onBufferedAmountLow", &WebSocketWrapper::onBufferedAmountLow),
45
- InstanceMethod("onMessage", &WebSocketWrapper::onMessage),
46
- InstanceMethod("remoteAddress", &WebSocketWrapper::remoteAddress),
47
- InstanceMethod("path", &WebSocketWrapper::path),
48
- });
49
-
50
- // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
51
- if(constructor.IsEmpty())
52
- {
53
- constructor = Napi::Persistent(func);
54
- constructor.SuppressDestruct();
55
- }
56
-
57
- exports.Set("WebSocket", func);
58
- return exports;
26
+ Napi::HandleScope scope(env);
27
+
28
+ Napi::Function func =
29
+ DefineClass(env, "WebSocket",
30
+ {
31
+ InstanceMethod("open", &WebSocketWrapper::open),
32
+ InstanceMethod("close", &WebSocketWrapper::close),
33
+ InstanceMethod("forceClose", &WebSocketWrapper::forceClose),
34
+ InstanceMethod("sendMessage", &WebSocketWrapper::sendMessage),
35
+ InstanceMethod("sendMessageBinary", &WebSocketWrapper::sendMessageBinary),
36
+ InstanceMethod("isOpen", &WebSocketWrapper::isOpen),
37
+ InstanceMethod("bufferedAmount", &WebSocketWrapper::bufferedAmount),
38
+ InstanceMethod("maxMessageSize", &WebSocketWrapper::maxMessageSize),
39
+ InstanceMethod("setBufferedAmountLowThreshold", &WebSocketWrapper::setBufferedAmountLowThreshold),
40
+ InstanceMethod("onOpen", &WebSocketWrapper::onOpen),
41
+ InstanceMethod("onClosed", &WebSocketWrapper::onClosed),
42
+ InstanceMethod("onError", &WebSocketWrapper::onError),
43
+ InstanceMethod("onBufferedAmountLow", &WebSocketWrapper::onBufferedAmountLow),
44
+ InstanceMethod("onMessage", &WebSocketWrapper::onMessage),
45
+ InstanceMethod("remoteAddress", &WebSocketWrapper::remoteAddress),
46
+ InstanceMethod("path", &WebSocketWrapper::path),
47
+ });
48
+
49
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
50
+ if (constructor.IsEmpty())
51
+ {
52
+ constructor = Napi::Persistent(func);
53
+ constructor.SuppressDestruct();
54
+ }
55
+
56
+ exports.Set("WebSocket", func);
57
+ return exports;
59
58
  }
60
59
 
61
60
  WebSocketWrapper::WebSocketWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<WebSocketWrapper>(info)
62
61
  {
63
- PLOG_DEBUG << "Constructor called";
64
- Napi::Env env = info.Env();
62
+ PLOG_DEBUG << "Constructor called";
63
+ Napi::Env env = info.Env();
64
+
65
+ // Create WebSocket using rtc::WebSocket provided by WebSocketServer
66
+ if (info.Length() > 1)
67
+ {
68
+ mWebSocketPtr = *(info[1].As<Napi::External<std::shared_ptr<rtc::WebSocket>>>().Data());
69
+ PLOG_DEBUG << "Using WebSocket got from WebSocketServer";
70
+ instances.insert(this);
65
71
 
66
- // Create WebSocket using rtc::WebSocket provided by WebSocketServer
67
- if (info.Length() > 1)
68
- {
69
- mWebSocketPtr = *(info[1].As<Napi::External<std::shared_ptr<rtc::WebSocket>>>().Data());
70
- PLOG_DEBUG << "Using WebSocket got from WebSocketServer";
71
- instances.insert(this);
72
+ // Closed callback must be set to trigger cleanup
73
+ mOnClosedCallback =
74
+ std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
75
+ return;
76
+ }
72
77
 
73
- // Closed callback must be set to trigger cleanup
74
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
75
- return;
78
+ // Create WebSocket without config
79
+ if (info.Length() == 0)
80
+ {
81
+ try
82
+ {
83
+ PLOG_DEBUG << "Creating a new WebSocket without config";
84
+ mWebSocketPtr = std::make_unique<rtc::WebSocket>();
76
85
  }
77
-
78
- // Create WebSocket without config
79
- if (info.Length() == 0)
86
+ catch (std::exception &ex)
80
87
  {
81
- try
82
- {
83
- PLOG_DEBUG << "Creating a new WebSocket without config";
84
- mWebSocketPtr = std::make_unique<rtc::WebSocket>();
85
- }
86
- catch (std::exception &ex)
87
- {
88
- Napi::Error::New(env, std::string("libdatachannel error while creating WebSocket without config: ") + ex.what()).ThrowAsJavaScriptException();
89
- return;
90
- }
91
- instances.insert(this);
92
-
93
- // Closed callback must be set to trigger cleanup
94
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
95
- return;
88
+ Napi::Error::New(env, std::string("libdatachannel error while creating WebSocket without config: ") + ex.what())
89
+ .ThrowAsJavaScriptException();
90
+ return;
96
91
  }
92
+ instances.insert(this);
97
93
 
98
- // Create WebSocket with config
99
- PLOG_DEBUG << "Creating a new WebSocket with config";
94
+ // Closed callback must be set to trigger cleanup
95
+ mOnClosedCallback =
96
+ std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
97
+ return;
98
+ }
100
99
 
101
- Napi::Object config = info[0].As<Napi::Object>();
102
- rtc::WebSocketConfiguration webSocketConfig;
100
+ // Create WebSocket with config
101
+ PLOG_DEBUG << "Creating a new WebSocket with config";
103
102
 
104
- if (config.Has("disableTlsVerification"))
103
+ Napi::Object config = info[0].As<Napi::Object>();
104
+ rtc::WebSocketConfiguration webSocketConfig;
105
+
106
+ if (config.Has("disableTlsVerification"))
107
+ {
108
+ if (!config.Get("disableTlsVerification").IsBoolean())
105
109
  {
106
- if (!config.Get("disableTlsVerification").IsBoolean())
107
- {
108
- Napi::TypeError::New(info.Env(), "disableTlsVerification must be boolean").ThrowAsJavaScriptException();
109
- return;
110
- }
111
- webSocketConfig.disableTlsVerification = config.Get("disableTlsVerification").ToBoolean();
110
+ Napi::TypeError::New(info.Env(), "disableTlsVerification must be boolean").ThrowAsJavaScriptException();
111
+ return;
112
112
  }
113
+ webSocketConfig.disableTlsVerification = config.Get("disableTlsVerification").ToBoolean();
114
+ }
113
115
 
114
- // Proxy Server
115
- if (config.Has("proxyServer") && config.Get("proxyServer").IsObject())
116
- {
117
- Napi::Object proxyServer = config.Get("proxyServer").As<Napi::Object>();
116
+ // Proxy Server
117
+ if (config.Has("proxyServer") && config.Get("proxyServer").IsObject())
118
+ {
119
+ Napi::Object proxyServer = config.Get("proxyServer").As<Napi::Object>();
118
120
 
119
- // IP
120
- std::string ip = proxyServer.Get("ip").As<Napi::String>();
121
+ // IP
122
+ std::string ip = proxyServer.Get("ip").As<Napi::String>();
121
123
 
122
- // Port
123
- uint16_t port = proxyServer.Get("port").As<Napi::Number>().Uint32Value();
124
+ // Port
125
+ uint16_t port = proxyServer.Get("port").As<Napi::Number>().Uint32Value();
124
126
 
125
- // Type
126
- std::string strType = proxyServer.Get("type").As<Napi::String>().ToString();
127
- rtc::ProxyServer::Type type = rtc::ProxyServer::Type::Http;
127
+ // Type
128
+ std::string strType = proxyServer.Get("type").As<Napi::String>().ToString();
129
+ rtc::ProxyServer::Type type = rtc::ProxyServer::Type::Http;
128
130
 
129
- if (strType == "Socks5")
130
- type = rtc::ProxyServer::Type::Socks5;
131
+ if (strType == "Socks5")
132
+ type = rtc::ProxyServer::Type::Socks5;
131
133
 
132
- // Username & Password
133
- std::string username = "";
134
- std::string password = "";
134
+ // Username & Password
135
+ std::string username = "";
136
+ std::string password = "";
135
137
 
136
- if (proxyServer.Get("username").IsString())
137
- username = proxyServer.Get("username").As<Napi::String>().ToString();
138
- if (proxyServer.Get("password").IsString())
139
- password = proxyServer.Get("password").As<Napi::String>().ToString();
138
+ if (proxyServer.Get("username").IsString())
139
+ username = proxyServer.Get("username").As<Napi::String>().ToString();
140
+ if (proxyServer.Get("password").IsString())
141
+ password = proxyServer.Get("password").As<Napi::String>().ToString();
140
142
 
141
- webSocketConfig.proxyServer = rtc::ProxyServer(type, ip, port, username, password);
142
- }
143
+ webSocketConfig.proxyServer = rtc::ProxyServer(type, ip, port, username, password);
144
+ }
143
145
 
144
- if (config.Has("protocols"))
146
+ if (config.Has("protocols"))
147
+ {
148
+ if (!config.Get("protocols").IsArray())
145
149
  {
146
- if (!config.Get("protocols").IsArray())
147
- {
148
- Napi::TypeError::New(info.Env(), "protocols must be an array").ThrowAsJavaScriptException();
149
- return;
150
- }
151
- Napi::Array protocols = config.Get("protocols").As<Napi::Array>();
152
- for (uint32_t i = 0; i < protocols.Length(); i++)
153
- {
154
- webSocketConfig.protocols.push_back(protocols.Get(i).ToString());
155
- }
150
+ Napi::TypeError::New(info.Env(), "protocols must be an array").ThrowAsJavaScriptException();
151
+ return;
156
152
  }
157
-
158
- if (config.Has("connectionTimeout"))
153
+ Napi::Array protocols = config.Get("protocols").As<Napi::Array>();
154
+ for (uint32_t i = 0; i < protocols.Length(); i++)
159
155
  {
160
- if (!config.Get("connectionTimeout").IsNumber())
161
- {
162
- Napi::TypeError::New(info.Env(), "connectionTimeout must be a number").ThrowAsJavaScriptException();
163
- return;
164
- }
165
- webSocketConfig.connectionTimeout = std::chrono::milliseconds(config.Get("connectionTimeout").ToNumber().Int64Value());
156
+ webSocketConfig.protocols.push_back(protocols.Get(i).ToString());
166
157
  }
158
+ }
167
159
 
168
- if (config.Has("pingInterval"))
160
+ if (config.Has("connectionTimeout"))
161
+ {
162
+ if (!config.Get("connectionTimeout").IsNumber())
169
163
  {
170
- if (!config.Get("pingInterval").IsNumber())
171
- {
172
- Napi::TypeError::New(info.Env(), "pingInterval must be a number").ThrowAsJavaScriptException();
173
- return;
174
- }
175
- webSocketConfig.pingInterval = std::chrono::milliseconds(config.Get("pingInterval").ToNumber().Int64Value());
164
+ Napi::TypeError::New(info.Env(), "connectionTimeout must be a number").ThrowAsJavaScriptException();
165
+ return;
176
166
  }
167
+ webSocketConfig.connectionTimeout =
168
+ std::chrono::milliseconds(config.Get("connectionTimeout").ToNumber().Int64Value());
169
+ }
177
170
 
178
- if (config.Has("maxOutstandingPings"))
171
+ if (config.Has("pingInterval"))
172
+ {
173
+ if (!config.Get("pingInterval").IsNumber())
179
174
  {
180
- if (!config.Get("maxOutstandingPings").IsNumber())
181
- {
182
- Napi::TypeError::New(info.Env(), "maxOutstandingPings must be a number").ThrowAsJavaScriptException();
183
- return;
184
- }
185
- webSocketConfig.maxOutstandingPings = config.Get("maxOutstandingPings").ToNumber().Int32Value();
175
+ Napi::TypeError::New(info.Env(), "pingInterval must be a number").ThrowAsJavaScriptException();
176
+ return;
186
177
  }
178
+ webSocketConfig.pingInterval = std::chrono::milliseconds(config.Get("pingInterval").ToNumber().Int64Value());
179
+ }
187
180
 
188
- if (config.Has("caCertificatePemFile"))
181
+ if (config.Has("maxOutstandingPings"))
182
+ {
183
+ if (!config.Get("maxOutstandingPings").IsNumber())
189
184
  {
190
- if (!config.Get("caCertificatePemFile").IsString())
191
- {
192
- Napi::TypeError::New(info.Env(), "caCertificatePemFile must be a string").ThrowAsJavaScriptException();
193
- return;
194
- }
195
- webSocketConfig.caCertificatePemFile = config.Get("caCertificatePemFile").ToString();
185
+ Napi::TypeError::New(info.Env(), "maxOutstandingPings must be a number").ThrowAsJavaScriptException();
186
+ return;
196
187
  }
188
+ webSocketConfig.maxOutstandingPings = config.Get("maxOutstandingPings").ToNumber().Int32Value();
189
+ }
197
190
 
198
- if (config.Has("certificatePemFile"))
191
+ if (config.Has("caCertificatePemFile"))
192
+ {
193
+ if (!config.Get("caCertificatePemFile").IsString())
199
194
  {
200
- if (!config.Get("certificatePemFile").IsString())
201
- {
202
- Napi::TypeError::New(info.Env(), "certificatePemFile must be a string").ThrowAsJavaScriptException();
203
- return;
204
- }
205
- webSocketConfig.certificatePemFile = config.Get("certificatePemFile").ToString();
195
+ Napi::TypeError::New(info.Env(), "caCertificatePemFile must be a string").ThrowAsJavaScriptException();
196
+ return;
206
197
  }
198
+ webSocketConfig.caCertificatePemFile = config.Get("caCertificatePemFile").ToString();
199
+ }
207
200
 
208
- if (config.Has("keyPemFile"))
201
+ if (config.Has("certificatePemFile"))
202
+ {
203
+ if (!config.Get("certificatePemFile").IsString())
209
204
  {
210
- if (!config.Get("keyPemFile").IsString())
211
- {
212
- Napi::TypeError::New(info.Env(), "keyPemFile must be a string").ThrowAsJavaScriptException();
213
- return;
214
- }
215
- webSocketConfig.keyPemFile = config.Get("keyPemFile").ToString();
205
+ Napi::TypeError::New(info.Env(), "certificatePemFile must be a string").ThrowAsJavaScriptException();
206
+ return;
216
207
  }
208
+ webSocketConfig.certificatePemFile = config.Get("certificatePemFile").ToString();
209
+ }
217
210
 
218
- if (config.Has("keyPemPass"))
211
+ if (config.Has("keyPemFile"))
212
+ {
213
+ if (!config.Get("keyPemFile").IsString())
219
214
  {
220
- if (!config.Get("keyPemPass").IsString())
221
- {
222
- Napi::TypeError::New(info.Env(), "keyPemPass must be a string").ThrowAsJavaScriptException();
223
- return;
224
- }
225
- webSocketConfig.keyPemPass = config.Get("keyPemPass").ToString();
215
+ Napi::TypeError::New(info.Env(), "keyPemFile must be a string").ThrowAsJavaScriptException();
216
+ return;
226
217
  }
218
+ webSocketConfig.keyPemFile = config.Get("keyPemFile").ToString();
219
+ }
227
220
 
228
- if (config.Has("maxMessageSize"))
221
+ if (config.Has("keyPemPass"))
222
+ {
223
+ if (!config.Get("keyPemPass").IsString())
229
224
  {
230
- if (!config.Get("maxMessageSize").IsNumber())
231
- {
232
- Napi::TypeError::New(info.Env(), "maxMessageSize must be a number").ThrowAsJavaScriptException();
233
- return;
234
- }
235
- webSocketConfig.maxMessageSize = config.Get("maxMessageSize").ToNumber().Int32Value();
225
+ Napi::TypeError::New(info.Env(), "keyPemPass must be a string").ThrowAsJavaScriptException();
226
+ return;
236
227
  }
228
+ webSocketConfig.keyPemPass = config.Get("keyPemPass").ToString();
229
+ }
237
230
 
238
- // Create WebSocket
239
- try
231
+ if (config.Has("maxMessageSize"))
232
+ {
233
+ if (!config.Get("maxMessageSize").IsNumber())
240
234
  {
241
- PLOG_DEBUG << "Creating a new WebSocket";
242
- mWebSocketPtr = std::make_unique<rtc::WebSocket>(webSocketConfig);
243
- }
244
- catch (std::exception &ex)
245
- {
246
- Napi::Error::New(env, std::string("libdatachannel error while creating WebSocket: ") + ex.what()).ThrowAsJavaScriptException();
247
- return;
235
+ Napi::TypeError::New(info.Env(), "maxMessageSize must be a number").ThrowAsJavaScriptException();
236
+ return;
248
237
  }
238
+ webSocketConfig.maxMessageSize = config.Get("maxMessageSize").ToNumber().Int32Value();
239
+ }
249
240
 
250
- PLOG_DEBUG << "WebSocket created";
241
+ // Create WebSocket
242
+ try
243
+ {
244
+ PLOG_DEBUG << "Creating a new WebSocket";
245
+ mWebSocketPtr = std::make_unique<rtc::WebSocket>(webSocketConfig);
246
+ }
247
+ catch (std::exception &ex)
248
+ {
249
+ Napi::Error::New(env, std::string("libdatachannel error while creating WebSocket: ") + ex.what())
250
+ .ThrowAsJavaScriptException();
251
+ return;
252
+ }
251
253
 
252
- // Closed callback must set to trigger cleanup
253
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
254
+ PLOG_DEBUG << "WebSocket created";
254
255
 
255
- instances.insert(this);
256
+ // Closed callback must set to trigger cleanup
257
+ mOnClosedCallback =
258
+ std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
259
+
260
+ instances.insert(this);
256
261
  }
257
262
 
258
263
  WebSocketWrapper::~WebSocketWrapper()
259
264
  {
260
- PLOG_DEBUG << "Destructor called";
261
- doClose();
265
+ PLOG_DEBUG << "Destructor called";
266
+ doClose();
262
267
  }
263
268
 
264
269
  void WebSocketWrapper::doClose()
265
270
  {
266
- PLOG_DEBUG << "doClose() called";
267
- if (mWebSocketPtr)
271
+ PLOG_DEBUG << "doClose() called";
272
+ if (mWebSocketPtr)
273
+ {
274
+ PLOG_DEBUG << "Closing...";
275
+ try
268
276
  {
269
- PLOG_DEBUG << "Closing...";
270
- try
271
- {
272
- mWebSocketPtr->close();
273
- mWebSocketPtr.reset();
274
- }
275
- catch (std::exception &ex)
276
- {
277
- std::cerr << std::string("libdatachannel error while closing WebSocket: ") + ex.what() << std::endl;
278
- return;
279
- }
277
+ mWebSocketPtr->close();
278
+ mWebSocketPtr.reset();
280
279
  }
280
+ catch (std::exception &ex)
281
+ {
282
+ std::cerr << std::string("libdatachannel error while closing WebSocket: ") + ex.what() << std::endl;
283
+ return;
284
+ }
285
+ }
281
286
 
282
- mOnOpenCallback.reset();
283
- mOnErrorCallback.reset();
284
- mOnBufferedAmountLowCallback.reset();
285
- mOnMessageCallback.reset();
287
+ mOnOpenCallback.reset();
288
+ mOnErrorCallback.reset();
289
+ mOnBufferedAmountLowCallback.reset();
290
+ mOnMessageCallback.reset();
286
291
  }
287
292
 
288
293
  void WebSocketWrapper::doForceClose()
289
294
  {
290
- PLOG_DEBUG << "doForceClose() called";
291
- if (mWebSocketPtr)
295
+ PLOG_DEBUG << "doForceClose() called";
296
+ if (mWebSocketPtr)
297
+ {
298
+ PLOG_DEBUG << "Force closing...";
299
+ try
292
300
  {
293
- PLOG_DEBUG << "Force closing...";
294
- try
295
- {
296
- mWebSocketPtr->forceClose();
297
- mWebSocketPtr.reset();
298
- }
299
- catch (std::exception &ex)
300
- {
301
- std::cerr << std::string("libdatachannel error while force closing WebSocket: ") + ex.what() << std::endl;
302
- return;
303
- }
301
+ mWebSocketPtr->forceClose();
302
+ mWebSocketPtr.reset();
303
+ }
304
+ catch (std::exception &ex)
305
+ {
306
+ std::cerr << std::string("libdatachannel error while force closing WebSocket: ") + ex.what() << std::endl;
307
+ return;
304
308
  }
309
+ }
305
310
 
306
- mOnOpenCallback.reset();
307
- mOnErrorCallback.reset();
308
- mOnBufferedAmountLowCallback.reset();
309
- mOnMessageCallback.reset();
311
+ mOnOpenCallback.reset();
312
+ mOnErrorCallback.reset();
313
+ mOnBufferedAmountLowCallback.reset();
314
+ mOnMessageCallback.reset();
310
315
  }
311
316
 
312
317
  void WebSocketWrapper::doCleanup()
313
318
  {
314
- PLOG_DEBUG << "doCleanup() called";
315
- mOnClosedCallback.reset();
316
- instances.erase(this);
319
+ PLOG_DEBUG << "doCleanup() called";
320
+ mOnClosedCallback.reset();
321
+ instances.erase(this);
317
322
  }
318
323
 
319
324
  void WebSocketWrapper::open(const Napi::CallbackInfo &info)
320
325
  {
321
- PLOG_DEBUG << "open() called";
322
- Napi::Env env = info.Env();
323
-
324
- if (!mWebSocketPtr)
325
- {
326
- Napi::Error::New(env, "open() called on destroyed WebSocket").ThrowAsJavaScriptException();
327
- return;
328
- }
329
- if (info.Length() < 1 || !info[0].IsString())
330
- {
331
- Napi::TypeError::New(env, "url must be string").ThrowAsJavaScriptException();
332
- return;
333
- }
334
-
335
- try
336
- {
337
- mWebSocketPtr->open(info[0].As<Napi::String>().ToString());
338
- }
339
- catch (std::exception &ex)
340
- {
341
- Napi::Error::New(env, std::string("libdatachannel error while opening WebSocket: ") + ex.what()).ThrowAsJavaScriptException();
342
- return;
343
- }
326
+ PLOG_DEBUG << "open() called";
327
+ Napi::Env env = info.Env();
328
+
329
+ if (!mWebSocketPtr)
330
+ {
331
+ Napi::Error::New(env, "open() called on destroyed WebSocket").ThrowAsJavaScriptException();
332
+ return;
333
+ }
334
+ if (info.Length() < 1 || !info[0].IsString())
335
+ {
336
+ Napi::TypeError::New(env, "url must be string").ThrowAsJavaScriptException();
337
+ return;
338
+ }
339
+
340
+ try
341
+ {
342
+ mWebSocketPtr->open(info[0].As<Napi::String>().ToString());
343
+ }
344
+ catch (std::exception &ex)
345
+ {
346
+ Napi::Error::New(env, std::string("libdatachannel error while opening WebSocket: ") + ex.what())
347
+ .ThrowAsJavaScriptException();
348
+ return;
349
+ }
344
350
  }
345
351
 
346
352
  void WebSocketWrapper::close(const Napi::CallbackInfo &info)
347
353
  {
348
- PLOG_DEBUG << "close() called";
349
- doClose();
354
+ PLOG_DEBUG << "close() called";
355
+ doClose();
350
356
  }
351
357
 
352
358
  void WebSocketWrapper::forceClose(const Napi::CallbackInfo &info)
353
359
  {
354
- PLOG_DEBUG << "forceClose() called";
355
- doForceClose();
360
+ PLOG_DEBUG << "forceClose() called";
361
+ doForceClose();
356
362
  }
357
363
 
358
364
  Napi::Value WebSocketWrapper::sendMessage(const Napi::CallbackInfo &info)
359
365
  {
360
- PLOG_DEBUG << "sendMessage() called";
361
- if (!mWebSocketPtr)
362
- {
363
- Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
364
- return info.Env().Null();
365
- }
366
-
367
- Napi::Env env = info.Env();
368
- int length = info.Length();
369
-
370
- // Allow call with NULL
371
- if (length < 1 || (!info[0].IsString() && !info[0].IsNull()))
372
- {
373
- Napi::TypeError::New(env, "String or Null expected").ThrowAsJavaScriptException();
374
- return info.Env().Null();
375
- }
376
-
377
- try
378
- {
379
- return Napi::Boolean::New(info.Env(), mWebSocketPtr->send(info[0].As<Napi::String>().ToString()));
380
- }
381
- catch (std::exception &ex)
382
- {
383
- Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
384
- return Napi::Boolean::New(info.Env(), false);
385
- }
366
+ PLOG_DEBUG << "sendMessage() called";
367
+ if (!mWebSocketPtr)
368
+ {
369
+ Napi::Error::New(info.Env(), "sendMessage() called on destroyed channel").ThrowAsJavaScriptException();
370
+ return info.Env().Null();
371
+ }
372
+
373
+ Napi::Env env = info.Env();
374
+ int length = info.Length();
375
+
376
+ // Allow call with NULL
377
+ if (length < 1 || (!info[0].IsString() && !info[0].IsNull()))
378
+ {
379
+ Napi::TypeError::New(env, "String or Null expected").ThrowAsJavaScriptException();
380
+ return info.Env().Null();
381
+ }
382
+
383
+ try
384
+ {
385
+ return Napi::Boolean::New(info.Env(), mWebSocketPtr->send(info[0].As<Napi::String>().ToString()));
386
+ }
387
+ catch (std::exception &ex)
388
+ {
389
+ Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
390
+ .ThrowAsJavaScriptException();
391
+ return Napi::Boolean::New(info.Env(), false);
392
+ }
386
393
  }
387
394
 
388
395
  Napi::Value WebSocketWrapper::sendMessageBinary(const Napi::CallbackInfo &info)
389
396
  {
390
- PLOG_DEBUG << "sendMessageBinary() called";
391
- if (!mWebSocketPtr)
392
- {
393
- Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
394
- return info.Env().Null();
395
- }
396
-
397
- Napi::Env env = info.Env();
398
- int length = info.Length();
399
-
400
- if (length < 1 || !info[0].IsBuffer())
401
- {
402
- Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
403
- return info.Env().Null();
404
- }
405
-
406
- try
407
- {
408
- Napi::Uint8Array buffer = info[0].As<Napi::Uint8Array>();
409
- return Napi::Boolean::New(info.Env(), mWebSocketPtr->send((std::byte *)buffer.Data(), buffer.ByteLength()));
410
- }
411
- catch (std::exception &ex)
412
- {
413
- Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what()).ThrowAsJavaScriptException();
414
- return Napi::Boolean::New(info.Env(), false);
415
- }
397
+ PLOG_DEBUG << "sendMessageBinary() called";
398
+ if (!mWebSocketPtr)
399
+ {
400
+ Napi::Error::New(info.Env(), "sendMessagBinary() called on destroyed channel").ThrowAsJavaScriptException();
401
+ return info.Env().Null();
402
+ }
403
+
404
+ Napi::Env env = info.Env();
405
+ int length = info.Length();
406
+
407
+ if (length < 1 || !info[0].IsBuffer())
408
+ {
409
+ Napi::TypeError::New(env, "Buffer expected").ThrowAsJavaScriptException();
410
+ return info.Env().Null();
411
+ }
412
+
413
+ try
414
+ {
415
+ Napi::Uint8Array buffer = info[0].As<Napi::Uint8Array>();
416
+ return Napi::Boolean::New(info.Env(), mWebSocketPtr->send((std::byte *)buffer.Data(), buffer.ByteLength()));
417
+ }
418
+ catch (std::exception &ex)
419
+ {
420
+ Napi::Error::New(env, std::string("libdatachannel error while sending data channel message: ") + ex.what())
421
+ .ThrowAsJavaScriptException();
422
+ return Napi::Boolean::New(info.Env(), false);
423
+ }
416
424
  }
417
425
 
418
426
  Napi::Value WebSocketWrapper::isOpen(const Napi::CallbackInfo &info)
419
427
  {
420
- PLOG_DEBUG << "isOpen() called";
421
- Napi::Env env = info.Env();
422
-
423
- if (!mWebSocketPtr)
424
- {
425
- return Napi::Boolean::New(info.Env(), false);
426
- }
427
-
428
- try
429
- {
430
- return Napi::Boolean::New(info.Env(), mWebSocketPtr->isOpen());
431
- }
432
- catch (std::exception &ex)
433
- {
434
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
435
- return Napi::Boolean::New(info.Env(), false);
436
- }
428
+ PLOG_DEBUG << "isOpen() called";
429
+ Napi::Env env = info.Env();
430
+
431
+ if (!mWebSocketPtr)
432
+ {
433
+ return Napi::Boolean::New(info.Env(), false);
434
+ }
435
+
436
+ try
437
+ {
438
+ return Napi::Boolean::New(info.Env(), mWebSocketPtr->isOpen());
439
+ }
440
+ catch (std::exception &ex)
441
+ {
442
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
443
+ return Napi::Boolean::New(info.Env(), false);
444
+ }
437
445
  }
438
446
 
439
447
  Napi::Value WebSocketWrapper::bufferedAmount(const Napi::CallbackInfo &info)
440
448
  {
441
- PLOG_DEBUG << "bufferedAmount() called";
442
- Napi::Env env = info.Env();
443
-
444
- if (!mWebSocketPtr)
445
- {
446
- return Napi::Number::New(info.Env(), 0);
447
- }
448
-
449
- try
450
- {
451
- return Napi::Number::New(info.Env(), mWebSocketPtr->bufferedAmount());
452
- }
453
- catch (std::exception &ex)
454
- {
455
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
456
- return Napi::Number::New(info.Env(), 0);
457
- }
449
+ PLOG_DEBUG << "bufferedAmount() called";
450
+ Napi::Env env = info.Env();
451
+
452
+ if (!mWebSocketPtr)
453
+ {
454
+ return Napi::Number::New(info.Env(), 0);
455
+ }
456
+
457
+ try
458
+ {
459
+ return Napi::Number::New(info.Env(), mWebSocketPtr->bufferedAmount());
460
+ }
461
+ catch (std::exception &ex)
462
+ {
463
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
464
+ return Napi::Number::New(info.Env(), 0);
465
+ }
458
466
  }
459
467
 
460
468
  Napi::Value WebSocketWrapper::maxMessageSize(const Napi::CallbackInfo &info)
461
469
  {
462
- PLOG_DEBUG << "maxMessageSize() called";
463
- Napi::Env env = info.Env();
464
-
465
- if (!mWebSocketPtr)
466
- {
467
- return Napi::Number::New(info.Env(), 0);
468
- }
469
-
470
- try
471
- {
472
- return Napi::Number::New(info.Env(), mWebSocketPtr->maxMessageSize());
473
- }
474
- catch (std::exception &ex)
475
- {
476
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
477
- return Napi::Number::New(info.Env(), 0);
478
- }
470
+ PLOG_DEBUG << "maxMessageSize() called";
471
+ Napi::Env env = info.Env();
472
+
473
+ if (!mWebSocketPtr)
474
+ {
475
+ return Napi::Number::New(info.Env(), 0);
476
+ }
477
+
478
+ try
479
+ {
480
+ return Napi::Number::New(info.Env(), mWebSocketPtr->maxMessageSize());
481
+ }
482
+ catch (std::exception &ex)
483
+ {
484
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
485
+ return Napi::Number::New(info.Env(), 0);
486
+ }
479
487
  }
480
488
 
481
489
  Napi::Value WebSocketWrapper::remoteAddress(const Napi::CallbackInfo &info)
482
490
  {
483
- PLOG_DEBUG << "remoteAddress() called";
484
- Napi::Env env = info.Env();
491
+ PLOG_DEBUG << "remoteAddress() called";
492
+ Napi::Env env = info.Env();
485
493
 
486
- if (!mWebSocketPtr)
487
- {
488
- return env.Undefined();
489
- }
494
+ if (!mWebSocketPtr)
495
+ {
496
+ return env.Undefined();
497
+ }
490
498
 
491
- try
499
+ try
500
+ {
501
+ auto address = mWebSocketPtr->remoteAddress();
502
+ if (address.has_value())
492
503
  {
493
- auto address = mWebSocketPtr->remoteAddress();
494
- if (address.has_value())
495
- {
496
- return Napi::String::New(info.Env(), address.value());
497
- }
498
- else
499
- {
500
- return env.Undefined();
501
- }
504
+ return Napi::String::New(info.Env(), address.value());
502
505
  }
503
- catch (std::exception &ex)
506
+ else
504
507
  {
505
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
506
- return env.Undefined();
508
+ return env.Undefined();
507
509
  }
510
+ }
511
+ catch (std::exception &ex)
512
+ {
513
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
514
+ return env.Undefined();
515
+ }
508
516
  }
509
517
 
510
518
  Napi::Value WebSocketWrapper::path(const Napi::CallbackInfo &info)
511
519
  {
512
- PLOG_DEBUG << "path() called";
513
- Napi::Env env = info.Env();
520
+ PLOG_DEBUG << "path() called";
521
+ Napi::Env env = info.Env();
514
522
 
515
- if (!mWebSocketPtr)
516
- {
517
- return env.Undefined();
518
- }
523
+ if (!mWebSocketPtr)
524
+ {
525
+ return env.Undefined();
526
+ }
519
527
 
520
- try
528
+ try
529
+ {
530
+ auto path = mWebSocketPtr->path();
531
+ if (path.has_value())
521
532
  {
522
- auto path = mWebSocketPtr->path();
523
- if (path.has_value())
524
- {
525
- return Napi::String::New(info.Env(), path.value());
526
- }
527
- else
528
- {
529
- return env.Undefined();
530
- }
533
+ return Napi::String::New(info.Env(), path.value());
531
534
  }
532
- catch (std::exception &ex)
535
+ else
533
536
  {
534
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
535
- return env.Undefined();
537
+ return env.Undefined();
536
538
  }
539
+ }
540
+ catch (std::exception &ex)
541
+ {
542
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
543
+ return env.Undefined();
544
+ }
537
545
  }
538
546
 
539
547
  void WebSocketWrapper::setBufferedAmountLowThreshold(const Napi::CallbackInfo &info)
540
548
  {
541
- PLOG_DEBUG << "setBufferedAmountLowThreshold() called";
542
- if (!mWebSocketPtr)
543
- {
544
- Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel").ThrowAsJavaScriptException();
545
- return;
546
- }
547
-
548
- Napi::Env env = info.Env();
549
- int length = info.Length();
550
-
551
- if (length < 1 || !info[0].IsNumber())
552
- {
553
- Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
554
- return;
555
- }
556
-
557
- try
558
- {
559
- mWebSocketPtr->setBufferedAmountLowThreshold(info[0].ToNumber().Uint32Value());
560
- }
561
- catch (std::exception &ex)
562
- {
563
- Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
564
- return;
565
- }
549
+ PLOG_DEBUG << "setBufferedAmountLowThreshold() called";
550
+ if (!mWebSocketPtr)
551
+ {
552
+ Napi::Error::New(info.Env(), "setBufferedAmountLowThreshold() called on destroyed channel")
553
+ .ThrowAsJavaScriptException();
554
+ return;
555
+ }
556
+
557
+ Napi::Env env = info.Env();
558
+ int length = info.Length();
559
+
560
+ if (length < 1 || !info[0].IsNumber())
561
+ {
562
+ Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
563
+ return;
564
+ }
565
+
566
+ try
567
+ {
568
+ mWebSocketPtr->setBufferedAmountLowThreshold(info[0].ToNumber().Uint32Value());
569
+ }
570
+ catch (std::exception &ex)
571
+ {
572
+ Napi::Error::New(env, std::string("libdatachannel error: ") + ex.what()).ThrowAsJavaScriptException();
573
+ return;
574
+ }
566
575
  }
567
576
 
568
577
  void WebSocketWrapper::onOpen(const Napi::CallbackInfo &info)
569
578
  {
570
- PLOG_DEBUG << "new onOpen() called";
571
- if (!mWebSocketPtr)
572
- {
573
- Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
574
- return;
575
- }
576
-
577
- Napi::Env env = info.Env();
578
- int length = info.Length();
579
-
580
- if (length < 1 || !info[0].IsFunction())
581
- {
582
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
583
- return;
584
- }
579
+ PLOG_DEBUG << "new onOpen() called";
580
+ if (!mWebSocketPtr)
581
+ {
582
+ Napi::Error::New(info.Env(), "onOpen() called on destroyed channel").ThrowAsJavaScriptException();
583
+ return;
584
+ }
585
+
586
+ Napi::Env env = info.Env();
587
+ int length = info.Length();
588
+
589
+ if (length < 1 || !info[0].IsFunction())
590
+ {
591
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
592
+ return;
593
+ }
594
+
595
+ // Callback
596
+ mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
597
+
598
+ mWebSocketPtr->onOpen(
599
+ [&]()
600
+ {
601
+ PLOG_DEBUG << "onOpen cb received from rtc";
602
+
603
+ if (mOnOpenCallback)
604
+ mOnOpenCallback->call(
605
+ [this](Napi::Env env, std::vector<napi_value> &args)
606
+ {
607
+ PLOG_DEBUG << "mOnOpenCallback call(1)";
608
+ // Check the WebSocket is not closed
609
+ if (instances.find(this) == instances.end())
610
+ {
611
+ PLOG_DEBUG << "WebSocket not found in instances";
612
+ throw ThreadSafeCallback::CancelException();
613
+ }
585
614
 
586
- // Callback
587
- mOnOpenCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
588
-
589
- mWebSocketPtr->onOpen([&]()
590
- {
591
- PLOG_DEBUG << "onOpen cb received from rtc";
592
-
593
- if (mOnOpenCallback)
594
- mOnOpenCallback->call([this](Napi::Env env, std::vector<napi_value> &args)
595
- {
596
- PLOG_DEBUG << "mOnOpenCallback call(1)";
597
- // Check the WebSocket is not closed
598
- if(instances.find(this) == instances.end())
599
- {
600
- PLOG_DEBUG << "WebSocket not found in instances";
601
- throw ThreadSafeCallback::CancelException();
602
- }
603
-
604
-
605
- // This will run in main thread and needs to construct the
606
- // arguments for the call
607
- args = {};
608
- PLOG_DEBUG << "mOnOpenCallback call(2)"; }); });
615
+ // This will run in main thread and needs to construct the
616
+ // arguments for the call
617
+ args = {};
618
+ PLOG_DEBUG << "mOnOpenCallback call(2)";
619
+ });
620
+ });
609
621
  }
610
622
 
611
623
  void WebSocketWrapper::onClosed(const Napi::CallbackInfo &info)
612
624
  {
613
- PLOG_DEBUG << "onClosed() called";
614
- if (!mWebSocketPtr)
615
- {
616
- Napi::Error::New(info.Env(), "onClosed() called on destroyed WebSocket").ThrowAsJavaScriptException();
617
- return;
618
- }
619
-
620
- Napi::Env env = info.Env();
621
- int length = info.Length();
622
-
623
- if (length < 1 || !info[0].IsFunction())
624
- {
625
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
626
- return;
627
- }
628
-
629
- // Callback
630
- mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
631
-
632
- mWebSocketPtr->onClosed([&]()
633
- {
634
- PLOG_DEBUG << "onClosed cb received from rtc";
635
- if (mOnClosedCallback)
636
- mOnClosedCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
637
- PLOG_DEBUG << "mOnClosedCallback call";
638
- // Do not check if the data channel has been closed here
639
-
640
- // This will run in main thread and needs to construct the
641
- // arguments for the call
642
- args = {};
643
- },[this]{
644
- doCleanup();
645
- }); });
625
+ PLOG_DEBUG << "onClosed() called";
626
+ if (!mWebSocketPtr)
627
+ {
628
+ Napi::Error::New(info.Env(), "onClosed() called on destroyed WebSocket").ThrowAsJavaScriptException();
629
+ return;
630
+ }
631
+
632
+ Napi::Env env = info.Env();
633
+ int length = info.Length();
634
+
635
+ if (length < 1 || !info[0].IsFunction())
636
+ {
637
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
638
+ return;
639
+ }
640
+
641
+ // Callback
642
+ mOnClosedCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
643
+
644
+ mWebSocketPtr->onClosed(
645
+ [&]()
646
+ {
647
+ PLOG_DEBUG << "onClosed cb received from rtc";
648
+ if (mOnClosedCallback)
649
+ mOnClosedCallback->call(
650
+ [this](Napi::Env env, std::vector<napi_value> &args)
651
+ {
652
+ PLOG_DEBUG << "mOnClosedCallback call";
653
+ // Do not check if the data channel has been closed here
654
+
655
+ // This will run in main thread and needs to construct the
656
+ // arguments for the call
657
+ args = {};
658
+ },
659
+ [this] { doCleanup(); });
660
+ });
646
661
  }
647
662
 
648
663
  void WebSocketWrapper::onError(const Napi::CallbackInfo &info)
649
664
  {
650
- PLOG_DEBUG << "onError() called";
651
- if (!mWebSocketPtr)
652
- {
653
- Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
654
- return;
655
- }
656
-
657
- Napi::Env env = info.Env();
658
- int length = info.Length();
659
-
660
- if (length < 1 || !info[0].IsFunction())
661
- {
662
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
663
- return;
664
- }
665
-
666
- // Callback
667
- mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
668
-
669
- mWebSocketPtr->onError([&](std::string error)
670
- {
671
- PLOG_DEBUG << "onError cb received from rtc";
672
- if (mOnErrorCallback)
673
- mOnErrorCallback->call([this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args) {
674
- PLOG_DEBUG << "mOnErrorCallback call(1)";
675
- // Check the data channel is not closed
676
- if(instances.find(this) == instances.end())
677
- throw ThreadSafeCallback::CancelException();
678
-
679
- // This will run in main thread and needs to construct the
680
- // arguments for the call
681
- args = {Napi::String::New(env, error)};
682
- PLOG_DEBUG << "mOnErrorCallback call(2)";
683
- }); });
665
+ PLOG_DEBUG << "onError() called";
666
+ if (!mWebSocketPtr)
667
+ {
668
+ Napi::Error::New(info.Env(), "onError() called on destroyed channel").ThrowAsJavaScriptException();
669
+ return;
670
+ }
671
+
672
+ Napi::Env env = info.Env();
673
+ int length = info.Length();
674
+
675
+ if (length < 1 || !info[0].IsFunction())
676
+ {
677
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
678
+ return;
679
+ }
680
+
681
+ // Callback
682
+ mOnErrorCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
683
+
684
+ mWebSocketPtr->onError(
685
+ [&](std::string error)
686
+ {
687
+ PLOG_DEBUG << "onError cb received from rtc";
688
+ if (mOnErrorCallback)
689
+ mOnErrorCallback->call(
690
+ [this, error = std::move(error)](Napi::Env env, std::vector<napi_value> &args)
691
+ {
692
+ PLOG_DEBUG << "mOnErrorCallback call(1)";
693
+ // Check the data channel is not closed
694
+ if (instances.find(this) == instances.end())
695
+ throw ThreadSafeCallback::CancelException();
696
+
697
+ // This will run in main thread and needs to construct the
698
+ // arguments for the call
699
+ args = {Napi::String::New(env, error)};
700
+ PLOG_DEBUG << "mOnErrorCallback call(2)";
701
+ });
702
+ });
684
703
  }
685
704
 
686
705
  void WebSocketWrapper::onBufferedAmountLow(const Napi::CallbackInfo &info)
687
706
  {
688
- PLOG_DEBUG << "onBufferedAmountLow() called";
689
- if (!mWebSocketPtr)
690
- {
691
- Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
692
- return;
693
- }
694
-
695
- Napi::Env env = info.Env();
696
- int length = info.Length();
697
-
698
- if (length < 1 || !info[0].IsFunction())
699
- {
700
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
701
- return;
702
- }
703
-
704
- // Callback
705
- mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
706
-
707
- mWebSocketPtr->onBufferedAmountLow([&]()
708
- {
709
- PLOG_DEBUG << "onBufferedAmountLow cb received from rtc";
710
- if (mOnBufferedAmountLowCallback)
711
- mOnBufferedAmountLowCallback->call([this](Napi::Env env, std::vector<napi_value> &args) {
712
- PLOG_DEBUG << "mOnBufferedAmountLowCallback call(1)";
713
- // Check the data channel is not closed
714
- if(instances.find(this) == instances.end())
715
- throw ThreadSafeCallback::CancelException();
716
-
717
- // This will run in main thread and needs to construct the
718
- // arguments for the call
719
- args = {};
720
- PLOG_DEBUG << "mOnBufferedAmountLowCallback call(2)";
721
- }); });
707
+ PLOG_DEBUG << "onBufferedAmountLow() called";
708
+ if (!mWebSocketPtr)
709
+ {
710
+ Napi::Error::New(info.Env(), "onBufferedAmountLow() called on destroyed channel").ThrowAsJavaScriptException();
711
+ return;
712
+ }
713
+
714
+ Napi::Env env = info.Env();
715
+ int length = info.Length();
716
+
717
+ if (length < 1 || !info[0].IsFunction())
718
+ {
719
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
720
+ return;
721
+ }
722
+
723
+ // Callback
724
+ mOnBufferedAmountLowCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
725
+
726
+ mWebSocketPtr->onBufferedAmountLow(
727
+ [&]()
728
+ {
729
+ PLOG_DEBUG << "onBufferedAmountLow cb received from rtc";
730
+ if (mOnBufferedAmountLowCallback)
731
+ mOnBufferedAmountLowCallback->call(
732
+ [this](Napi::Env env, std::vector<napi_value> &args)
733
+ {
734
+ PLOG_DEBUG << "mOnBufferedAmountLowCallback call(1)";
735
+ // Check the data channel is not closed
736
+ if (instances.find(this) == instances.end())
737
+ throw ThreadSafeCallback::CancelException();
738
+
739
+ // This will run in main thread and needs to construct the
740
+ // arguments for the call
741
+ args = {};
742
+ PLOG_DEBUG << "mOnBufferedAmountLowCallback call(2)";
743
+ });
744
+ });
722
745
  }
723
746
 
724
747
  void WebSocketWrapper::onMessage(const Napi::CallbackInfo &info)
725
748
  {
726
- PLOG_DEBUG << "onMessage() called";
727
- if (!mWebSocketPtr)
728
- {
729
- Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
730
- return;
731
- }
732
-
733
- Napi::Env env = info.Env();
734
- int length = info.Length();
735
-
736
- if (length < 1 || !info[0].IsFunction())
737
- {
738
- Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
739
- return;
740
- }
741
-
742
- // Callback
743
- mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
744
-
745
- PLOG_DEBUG << "setting onMessage cb on mWebSocketPtr";
746
- mWebSocketPtr->onMessage([&](std::variant<rtc::binary, std::string> message)
747
- {
748
- PLOG_DEBUG << "onMessage cb received from rtc";
749
- if (mOnMessageCallback)
750
- mOnMessageCallback->call([this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args) {
751
- PLOG_DEBUG << "mOnMessageCallback call(1)";
752
- // Check the data channel is not closed
753
- if(instances.find(this) == instances.end())
754
- throw ThreadSafeCallback::CancelException();
755
-
756
- // This will run in main thread and needs to construct the
757
- // arguments for the call
758
- if (std::holds_alternative<std::string>(message))
759
- {
760
- args = {Napi::String::New(env, std::get<std::string>(message))};
761
- }
762
- else
763
- {
764
- auto bin = std::get<rtc::binary>(std::move(message));
765
- args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
766
- }
767
- PLOG_DEBUG << "mOnMessageCallback call(2)";
768
- }); });
749
+ PLOG_DEBUG << "onMessage() called";
750
+ if (!mWebSocketPtr)
751
+ {
752
+ Napi::Error::New(info.Env(), "onMessage() called on destroyed channel").ThrowAsJavaScriptException();
753
+ return;
754
+ }
755
+
756
+ Napi::Env env = info.Env();
757
+ int length = info.Length();
758
+
759
+ if (length < 1 || !info[0].IsFunction())
760
+ {
761
+ Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
762
+ return;
763
+ }
764
+
765
+ // Callback
766
+ mOnMessageCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
767
+
768
+ PLOG_DEBUG << "setting onMessage cb on mWebSocketPtr";
769
+ mWebSocketPtr->onMessage(
770
+ [&](std::variant<rtc::binary, std::string> message)
771
+ {
772
+ PLOG_DEBUG << "onMessage cb received from rtc";
773
+ if (mOnMessageCallback)
774
+ mOnMessageCallback->call(
775
+ [this, message = std::move(message)](Napi::Env env, std::vector<napi_value> &args)
776
+ {
777
+ PLOG_DEBUG << "mOnMessageCallback call(1)";
778
+ // Check the data channel is not closed
779
+ if (instances.find(this) == instances.end())
780
+ throw ThreadSafeCallback::CancelException();
781
+
782
+ // This will run in main thread and needs to construct the
783
+ // arguments for the call
784
+ if (std::holds_alternative<std::string>(message))
785
+ {
786
+ args = {Napi::String::New(env, std::get<std::string>(message))};
787
+ }
788
+ else
789
+ {
790
+ auto bin = std::get<rtc::binary>(std::move(message));
791
+ args = {Napi::Buffer<std::byte>::Copy(env, bin.data(), bin.size())};
792
+ }
793
+ PLOG_DEBUG << "mOnMessageCallback call(2)";
794
+ });
795
+ });
769
796
  }