@lng2004/node-datachannel 0.31.0-20251228
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/.clang-format +17 -0
- package/.editorconfig +12 -0
- package/.eslintignore +8 -0
- package/.eslintrc.json +27 -0
- package/.gitmodules +3 -0
- package/.prettierignore +7 -0
- package/.prettierrc +13 -0
- package/API.md +247 -0
- package/BULDING.md +33 -0
- package/CMakeLists.txt +134 -0
- package/LICENSE +373 -0
- package/README.md +130 -0
- package/dist/cjs/index.cjs +11 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/lib/datachannel-stream.cjs +101 -0
- package/dist/cjs/lib/datachannel-stream.cjs.map +1 -0
- package/dist/cjs/lib/index.cjs +88 -0
- package/dist/cjs/lib/index.cjs.map +1 -0
- package/dist/cjs/lib/node-datachannel.cjs +8 -0
- package/dist/cjs/lib/node-datachannel.cjs.map +1 -0
- package/dist/cjs/lib/websocket-server.cjs +45 -0
- package/dist/cjs/lib/websocket-server.cjs.map +1 -0
- package/dist/cjs/lib/websocket.cjs +8 -0
- package/dist/cjs/lib/websocket.cjs.map +1 -0
- package/dist/cjs/polyfill/Events.cjs +86 -0
- package/dist/cjs/polyfill/Events.cjs.map +1 -0
- package/dist/cjs/polyfill/Exception.cjs +34 -0
- package/dist/cjs/polyfill/Exception.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCCertificate.cjs +34 -0
- package/dist/cjs/polyfill/RTCCertificate.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCDataChannel.cjs +214 -0
- package/dist/cjs/polyfill/RTCDataChannel.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCDtlsTransport.cjs +53 -0
- package/dist/cjs/polyfill/RTCDtlsTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCError.cjs +83 -0
- package/dist/cjs/polyfill/RTCError.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCIceCandidate.cjs +132 -0
- package/dist/cjs/polyfill/RTCIceCandidate.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCIceTransport.cjs +94 -0
- package/dist/cjs/polyfill/RTCIceTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCPeerConnection.cjs +434 -0
- package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCSctpTransport.cjs +59 -0
- package/dist/cjs/polyfill/RTCSctpTransport.cjs.map +1 -0
- package/dist/cjs/polyfill/RTCSessionDescription.cjs +45 -0
- package/dist/cjs/polyfill/RTCSessionDescription.cjs.map +1 -0
- package/dist/cjs/polyfill/index.cjs +42 -0
- package/dist/cjs/polyfill/index.cjs.map +1 -0
- package/dist/esm/index.mjs +8 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/lib/datachannel-stream.mjs +78 -0
- package/dist/esm/lib/datachannel-stream.mjs.map +1 -0
- package/dist/esm/lib/index.mjs +62 -0
- package/dist/esm/lib/index.mjs.map +1 -0
- package/dist/esm/lib/node-datachannel.mjs +12 -0
- package/dist/esm/lib/node-datachannel.mjs.map +1 -0
- package/dist/esm/lib/websocket-server.mjs +43 -0
- package/dist/esm/lib/websocket-server.mjs.map +1 -0
- package/dist/esm/lib/websocket.mjs +6 -0
- package/dist/esm/lib/websocket.mjs.map +1 -0
- package/dist/esm/polyfill/Events.mjs +82 -0
- package/dist/esm/polyfill/Events.mjs.map +1 -0
- package/dist/esm/polyfill/Exception.mjs +28 -0
- package/dist/esm/polyfill/Exception.mjs.map +1 -0
- package/dist/esm/polyfill/RTCCertificate.mjs +30 -0
- package/dist/esm/polyfill/RTCCertificate.mjs.map +1 -0
- package/dist/esm/polyfill/RTCDataChannel.mjs +210 -0
- package/dist/esm/polyfill/RTCDataChannel.mjs.map +1 -0
- package/dist/esm/polyfill/RTCDtlsTransport.mjs +49 -0
- package/dist/esm/polyfill/RTCDtlsTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCError.mjs +79 -0
- package/dist/esm/polyfill/RTCError.mjs.map +1 -0
- package/dist/esm/polyfill/RTCIceCandidate.mjs +128 -0
- package/dist/esm/polyfill/RTCIceCandidate.mjs.map +1 -0
- package/dist/esm/polyfill/RTCIceTransport.mjs +89 -0
- package/dist/esm/polyfill/RTCIceTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCPeerConnection.mjs +430 -0
- package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -0
- package/dist/esm/polyfill/RTCSctpTransport.mjs +55 -0
- package/dist/esm/polyfill/RTCSctpTransport.mjs.map +1 -0
- package/dist/esm/polyfill/RTCSessionDescription.mjs +41 -0
- package/dist/esm/polyfill/RTCSessionDescription.mjs.map +1 -0
- package/dist/esm/polyfill/index.mjs +27 -0
- package/dist/esm/polyfill/index.mjs.map +1 -0
- package/dist/types/lib/datachannel-stream.d.ts +24 -0
- package/dist/types/lib/index.d.ts +235 -0
- package/dist/types/lib/types.d.ts +118 -0
- package/dist/types/lib/websocket-server.d.ts +13 -0
- package/dist/types/lib/websocket.d.ts +25 -0
- package/dist/types/polyfill/Events.d.ts +15 -0
- package/dist/types/polyfill/RTCCertificate.d.ts +9 -0
- package/dist/types/polyfill/RTCDataChannel.d.ts +29 -0
- package/dist/types/polyfill/RTCDtlsTransport.d.ts +15 -0
- package/dist/types/polyfill/RTCError.d.ts +17 -0
- package/dist/types/polyfill/RTCIceCandidate.d.ts +21 -0
- package/dist/types/polyfill/RTCIceTransport.d.ts +30 -0
- package/dist/types/polyfill/RTCPeerConnection.d.ts +64 -0
- package/dist/types/polyfill/RTCSctpTransport.d.ts +15 -0
- package/dist/types/polyfill/RTCSessionDescription.d.ts +10 -0
- package/dist/types/polyfill/index.d.ts +26 -0
- package/jest.config.ts +14 -0
- package/package.json +121 -0
- package/rollup.config.mjs +72 -0
- package/src/cpp/data-channel-wrapper.cpp +530 -0
- package/src/cpp/data-channel-wrapper.h +63 -0
- package/src/cpp/ice-udp-mux-listener-wrapper.cpp +157 -0
- package/src/cpp/ice-udp-mux-listener-wrapper.h +43 -0
- package/src/cpp/main.cpp +58 -0
- package/src/cpp/media-audio-wrapper.cpp +457 -0
- package/src/cpp/media-audio-wrapper.h +52 -0
- package/src/cpp/media-av1packetization.cpp +24 -0
- package/src/cpp/media-av1packetization.h +11 -0
- package/src/cpp/media-av1rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-av1rtppacketizer-wrapper.h +29 -0
- package/src/cpp/media-direction.cpp +43 -0
- package/src/cpp/media-direction.h +10 -0
- package/src/cpp/media-h264rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-h264rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-h265rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-h265rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-h26xseparator.cpp +32 -0
- package/src/cpp/media-h26xseparator.h +11 -0
- package/src/cpp/media-mediahandler-helper.cpp +31 -0
- package/src/cpp/media-mediahandler-helper.h +11 -0
- package/src/cpp/media-pacinghandler-wrapper.cpp +79 -0
- package/src/cpp/media-pacinghandler-wrapper.h +28 -0
- package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
- package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
- package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +57 -0
- package/src/cpp/media-rtcpreceivingsession-wrapper.h +28 -0
- package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
- package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
- package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
- package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
- package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
- package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-track-wrapper.cpp +458 -0
- package/src/cpp/media-track-wrapper.h +61 -0
- package/src/cpp/media-video-wrapper.cpp +526 -0
- package/src/cpp/media-video-wrapper.h +56 -0
- package/src/cpp/peer-connection-wrapper.cpp +1298 -0
- package/src/cpp/peer-connection-wrapper.h +89 -0
- package/src/cpp/rtc-wrapper.cpp +205 -0
- package/src/cpp/rtc-wrapper.h +24 -0
- package/src/cpp/thread-safe-callback.cpp +57 -0
- package/src/cpp/thread-safe-callback.h +47 -0
- package/src/cpp/web-socket-server-wrapper.cpp +275 -0
- package/src/cpp/web-socket-server-wrapper.h +41 -0
- package/src/cpp/web-socket-wrapper.cpp +796 -0
- package/src/cpp/web-socket-wrapper.h +63 -0
- package/src/index.ts +9 -0
- package/src/lib/datachannel-stream.ts +100 -0
- package/src/lib/index.ts +283 -0
- package/src/lib/node-datachannel.ts +3 -0
- package/src/lib/types.ts +168 -0
- package/src/lib/websocket-server.ts +37 -0
- package/src/lib/websocket.ts +26 -0
- package/src/polyfill/Events.ts +82 -0
- package/src/polyfill/Exception.ts +37 -0
- package/src/polyfill/README.md +41 -0
- package/src/polyfill/RTCCertificate.ts +21 -0
- package/src/polyfill/RTCDataChannel.ts +225 -0
- package/src/polyfill/RTCDtlsTransport.ts +46 -0
- package/src/polyfill/RTCError.ts +78 -0
- package/src/polyfill/RTCIceCandidate.ts +128 -0
- package/src/polyfill/RTCIceTransport.ts +90 -0
- package/src/polyfill/RTCPeerConnection.ts +527 -0
- package/src/polyfill/RTCSctpTransport.ts +51 -0
- package/src/polyfill/RTCSessionDescription.ts +41 -0
- package/src/polyfill/index.ts +38 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#ifndef WEB_SOCKET_WRAPPER_H
|
|
2
|
+
#define WEB_SOCKET_WRAPPER_H
|
|
3
|
+
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <unordered_set>
|
|
6
|
+
|
|
7
|
+
#include <napi.h>
|
|
8
|
+
#include <rtc/rtc.hpp>
|
|
9
|
+
|
|
10
|
+
#include "thread-safe-callback.h"
|
|
11
|
+
|
|
12
|
+
class WebSocketWrapper : public Napi::ObjectWrap<WebSocketWrapper>
|
|
13
|
+
{
|
|
14
|
+
public:
|
|
15
|
+
static Napi::FunctionReference constructor;
|
|
16
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
17
|
+
WebSocketWrapper(const Napi::CallbackInfo &info);
|
|
18
|
+
~WebSocketWrapper();
|
|
19
|
+
|
|
20
|
+
// Functions
|
|
21
|
+
void open(const Napi::CallbackInfo &info);
|
|
22
|
+
void close(const Napi::CallbackInfo &info);
|
|
23
|
+
void forceClose(const Napi::CallbackInfo &info);
|
|
24
|
+
Napi::Value sendMessage(const Napi::CallbackInfo &info);
|
|
25
|
+
Napi::Value sendMessageBinary(const Napi::CallbackInfo &info);
|
|
26
|
+
Napi::Value isOpen(const Napi::CallbackInfo &info);
|
|
27
|
+
Napi::Value bufferedAmount(const Napi::CallbackInfo &info);
|
|
28
|
+
Napi::Value maxMessageSize(const Napi::CallbackInfo &info);
|
|
29
|
+
void setBufferedAmountLowThreshold(const Napi::CallbackInfo &info);
|
|
30
|
+
Napi::Value remoteAddress(const Napi::CallbackInfo &info);
|
|
31
|
+
Napi::Value path(const Napi::CallbackInfo &info);
|
|
32
|
+
|
|
33
|
+
// Callbacks
|
|
34
|
+
void onOpen(const Napi::CallbackInfo &info);
|
|
35
|
+
void onClosed(const Napi::CallbackInfo &info);
|
|
36
|
+
void onError(const Napi::CallbackInfo &info);
|
|
37
|
+
void onBufferedAmountLow(const Napi::CallbackInfo &info);
|
|
38
|
+
void onMessage(const Napi::CallbackInfo &info);
|
|
39
|
+
|
|
40
|
+
// Close all existing WebSockets
|
|
41
|
+
static void CloseAll();
|
|
42
|
+
|
|
43
|
+
// Reset all Callbacks for existing WebSockets
|
|
44
|
+
static void CleanupAll();
|
|
45
|
+
|
|
46
|
+
private:
|
|
47
|
+
static std::unordered_set<WebSocketWrapper *> instances;
|
|
48
|
+
|
|
49
|
+
void doClose();
|
|
50
|
+
void doForceClose();
|
|
51
|
+
void doCleanup();
|
|
52
|
+
|
|
53
|
+
std::shared_ptr<rtc::WebSocket> mWebSocketPtr = nullptr;
|
|
54
|
+
|
|
55
|
+
// Callback Ptrs
|
|
56
|
+
std::unique_ptr<ThreadSafeCallback> mOnOpenCallback = nullptr;
|
|
57
|
+
std::unique_ptr<ThreadSafeCallback> mOnClosedCallback = nullptr;
|
|
58
|
+
std::unique_ptr<ThreadSafeCallback> mOnErrorCallback = nullptr;
|
|
59
|
+
std::unique_ptr<ThreadSafeCallback> mOnBufferedAmountLowCallback = nullptr;
|
|
60
|
+
std::unique_ptr<ThreadSafeCallback> mOnMessageCallback = nullptr;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
#endif // WEB_SOCKET_WRAPPER_H
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// This file is created for builder process
|
|
2
|
+
// So builder can find and compile all files and folders
|
|
3
|
+
// Not intended to be imported directly
|
|
4
|
+
|
|
5
|
+
import n from './lib/index';
|
|
6
|
+
import p from './polyfill/index';
|
|
7
|
+
|
|
8
|
+
export const nodeDataChannel = n;
|
|
9
|
+
export const polyfill = p;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import * as stream from 'stream';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Turns a node-datachannel DataChannel into a real Node.js stream, complete with buffering,
|
|
6
|
+
* backpressure (up to a point - if the buffer fills up, messages are dropped), and
|
|
7
|
+
* support for piping data elsewhere.
|
|
8
|
+
*
|
|
9
|
+
* Read & written data may be either UTF-8 strings or Buffers - this difference exists at
|
|
10
|
+
* the protocol level, and is preserved here throughout.
|
|
11
|
+
*/
|
|
12
|
+
export default class DataChannelStream extends stream.Duplex {
|
|
13
|
+
private _rawChannel: any;
|
|
14
|
+
private _readActive: boolean;
|
|
15
|
+
|
|
16
|
+
constructor(rawChannel: any, streamOptions?: Omit<stream.DuplexOptions, 'objectMode'>) {
|
|
17
|
+
super({
|
|
18
|
+
allowHalfOpen: false, // Default to autoclose on end().
|
|
19
|
+
...streamOptions,
|
|
20
|
+
objectMode: true, // Preserve the string/buffer distinction (WebRTC treats them differently)
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
this._rawChannel = rawChannel;
|
|
24
|
+
this._readActive = true;
|
|
25
|
+
|
|
26
|
+
rawChannel.onMessage((msg: any) => {
|
|
27
|
+
if (!this._readActive) return; // If the buffer is full, drop messages.
|
|
28
|
+
|
|
29
|
+
// If the push is rejected, we pause reading until the next call to _read().
|
|
30
|
+
this._readActive = this.push(msg);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// When the DataChannel closes, the readable & writable ends close
|
|
34
|
+
rawChannel.onClosed(() => {
|
|
35
|
+
this.push(null);
|
|
36
|
+
this.destroy();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
rawChannel.onError((errMsg: string) => {
|
|
40
|
+
this.destroy(new Error(`DataChannel error: ${errMsg}`));
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Buffer all writes until the DataChannel opens
|
|
44
|
+
if (!rawChannel.isOpen()) {
|
|
45
|
+
this.cork();
|
|
46
|
+
rawChannel.onOpen(() => this.uncork());
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_read(): void {
|
|
51
|
+
// Stop dropping messages, if the buffer filling up meant we were doing so before.
|
|
52
|
+
this._readActive = true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
_write(chunk, _encoding, callback): void {
|
|
56
|
+
let sentOk;
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
if (Buffer.isBuffer(chunk)) {
|
|
60
|
+
sentOk = this._rawChannel.sendMessageBinary(chunk);
|
|
61
|
+
} else if (typeof chunk === 'string') {
|
|
62
|
+
sentOk = this._rawChannel.sendMessage(chunk);
|
|
63
|
+
} else {
|
|
64
|
+
const typeName = chunk.constructor.name || typeof chunk;
|
|
65
|
+
throw new Error(`Cannot write ${typeName} to DataChannel stream`);
|
|
66
|
+
}
|
|
67
|
+
} catch (err) {
|
|
68
|
+
return callback(err);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (sentOk) {
|
|
72
|
+
callback(null);
|
|
73
|
+
} else {
|
|
74
|
+
callback(new Error('Failed to write to DataChannel'));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
_final(callback): void {
|
|
79
|
+
if (!this.allowHalfOpen) this.destroy();
|
|
80
|
+
callback(null);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
_destroy(maybeErr, callback): void {
|
|
84
|
+
// When the stream is destroyed, we close the DataChannel.
|
|
85
|
+
this._rawChannel.close();
|
|
86
|
+
callback(maybeErr);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get label(): string {
|
|
90
|
+
return this._rawChannel.getLabel();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
get id(): number {
|
|
94
|
+
return this._rawChannel.getId();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get protocol(): string {
|
|
98
|
+
return this._rawChannel.getProtocol();
|
|
99
|
+
}
|
|
100
|
+
}
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import nodeDataChannel from './node-datachannel';
|
|
2
|
+
import _DataChannelStream from './datachannel-stream';
|
|
3
|
+
import { WebSocketServer } from './websocket-server';
|
|
4
|
+
import {
|
|
5
|
+
Channel,
|
|
6
|
+
DataChannelInitConfig,
|
|
7
|
+
DescriptionType,
|
|
8
|
+
Direction,
|
|
9
|
+
LogLevel,
|
|
10
|
+
NalUnitSeparator,
|
|
11
|
+
ObuPacketization,
|
|
12
|
+
RtcConfig,
|
|
13
|
+
RTCIceConnectionState,
|
|
14
|
+
RTCIceGatheringState,
|
|
15
|
+
RTCPeerConnectionState,
|
|
16
|
+
RTCSignalingState,
|
|
17
|
+
SctpSettings,
|
|
18
|
+
SelectedCandidateInfo,
|
|
19
|
+
} from './types';
|
|
20
|
+
import { WebSocket } from './websocket';
|
|
21
|
+
import type { CertificateFingerprint, IceUdpMuxRequest, LocalDescriptionInit } from './types';
|
|
22
|
+
|
|
23
|
+
export function preload(): void {
|
|
24
|
+
nodeDataChannel.preload();
|
|
25
|
+
}
|
|
26
|
+
export function initLogger(level: LogLevel): void {
|
|
27
|
+
nodeDataChannel.initLogger(level);
|
|
28
|
+
}
|
|
29
|
+
export function cleanup(): void {
|
|
30
|
+
nodeDataChannel.cleanup();
|
|
31
|
+
}
|
|
32
|
+
export function setSctpSettings(settings: SctpSettings): void {
|
|
33
|
+
nodeDataChannel.setSctpSettings(settings);
|
|
34
|
+
}
|
|
35
|
+
export function getLibraryVersion(): string {
|
|
36
|
+
return nodeDataChannel.getLibraryVersion();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface Audio {
|
|
40
|
+
addAudioCodec(payloadType: number, codec: string, profile?: string): void;
|
|
41
|
+
addOpusCodec(payloadType: number, profile?: string): string;
|
|
42
|
+
direction(): Direction;
|
|
43
|
+
generateSdp(eol: string, addr: string, port: number): string;
|
|
44
|
+
mid(): string;
|
|
45
|
+
setDirection(dir: Direction): void;
|
|
46
|
+
description(): string;
|
|
47
|
+
removeFormat(fmt: string): void;
|
|
48
|
+
addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;
|
|
49
|
+
removeSSRC(ssrc: number): void;
|
|
50
|
+
replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;
|
|
51
|
+
hasSSRC(ssrc: number): boolean;
|
|
52
|
+
getSSRCs(): number[];
|
|
53
|
+
getCNameForSsrc(ssrc: number): string;
|
|
54
|
+
setBitrate(bitRate: number): void;
|
|
55
|
+
getBitrate(): number;
|
|
56
|
+
hasPayloadType(payloadType: number): boolean;
|
|
57
|
+
addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;
|
|
58
|
+
addRTPMap(): void;
|
|
59
|
+
parseSdpLine(line: string): void;
|
|
60
|
+
}
|
|
61
|
+
export const Audio: {
|
|
62
|
+
new (mid: string, dir: Direction): Audio;
|
|
63
|
+
} = nodeDataChannel.Audio;
|
|
64
|
+
|
|
65
|
+
export interface Video {
|
|
66
|
+
addVideoCodec(payloadType: number, codec: string, profile?: string): void;
|
|
67
|
+
addH264Codec(payloadType: number, profile?: string): void;
|
|
68
|
+
addH265Codec(payloadType: number): void;
|
|
69
|
+
addVP8Codec(payloadType: number): void;
|
|
70
|
+
addVP9Codec(payloadType: number): void;
|
|
71
|
+
addAV1Codec(payloadType: number): void;
|
|
72
|
+
direction(): Direction;
|
|
73
|
+
generateSdp(eol: string, addr: string, port: number): string;
|
|
74
|
+
mid(): string;
|
|
75
|
+
setDirection(dir: Direction): void;
|
|
76
|
+
description(): string;
|
|
77
|
+
removeFormat(fmt: string): void;
|
|
78
|
+
addSSRC(ssrc: number, name?: string, msid?: string, trackID?: string): void;
|
|
79
|
+
removeSSRC(ssrc: number): void;
|
|
80
|
+
replaceSSRC(oldSsrc: number, ssrc: number, name?: string, msid?: string, trackID?: string): void;
|
|
81
|
+
hasSSRC(ssrc: number): boolean;
|
|
82
|
+
getSSRCs(): number[];
|
|
83
|
+
getCNameForSsrc(ssrc: number): string;
|
|
84
|
+
setBitrate(bitRate: number): void;
|
|
85
|
+
getBitrate(): number;
|
|
86
|
+
hasPayloadType(payloadType: number): boolean;
|
|
87
|
+
addRTXCodec(payloadType: number, originalPayloadType: number, clockRate: number): void;
|
|
88
|
+
addRTPMap(): void;
|
|
89
|
+
parseSdpLine(line: string): void;
|
|
90
|
+
}
|
|
91
|
+
export const Video: {
|
|
92
|
+
new (mid: string, dir: Direction): Video;
|
|
93
|
+
} = nodeDataChannel.Video;
|
|
94
|
+
|
|
95
|
+
export interface Track {
|
|
96
|
+
direction(): Direction;
|
|
97
|
+
mid(): string;
|
|
98
|
+
type(): string;
|
|
99
|
+
close(): void;
|
|
100
|
+
sendMessage(msg: string): boolean;
|
|
101
|
+
sendMessageBinary(buffer: Buffer): boolean;
|
|
102
|
+
isOpen(): boolean;
|
|
103
|
+
isClosed(): boolean;
|
|
104
|
+
bufferedAmount(): number;
|
|
105
|
+
maxMessageSize(): number;
|
|
106
|
+
requestBitrate(bitRate: number): boolean;
|
|
107
|
+
setBufferedAmountLowThreshold(newSize: number): void;
|
|
108
|
+
requestKeyframe(): boolean;
|
|
109
|
+
setMediaHandler(handler: MediaHandler): void;
|
|
110
|
+
onOpen(cb: () => void): void;
|
|
111
|
+
onClosed(cb: () => void): void;
|
|
112
|
+
onError(cb: (err: string) => void): void;
|
|
113
|
+
onMessage(cb: (msg: Buffer) => void): void;
|
|
114
|
+
}
|
|
115
|
+
export const Track: {
|
|
116
|
+
new (): Track;
|
|
117
|
+
} = nodeDataChannel.Track;
|
|
118
|
+
|
|
119
|
+
export interface DataChannel extends Channel {
|
|
120
|
+
getLabel(): string;
|
|
121
|
+
getId(): number;
|
|
122
|
+
getProtocol(): string;
|
|
123
|
+
|
|
124
|
+
// Channel implementation
|
|
125
|
+
close(): void;
|
|
126
|
+
sendMessage(msg: string): boolean;
|
|
127
|
+
sendMessageBinary(buffer: Buffer | Uint8Array): boolean;
|
|
128
|
+
isOpen(): boolean;
|
|
129
|
+
bufferedAmount(): number;
|
|
130
|
+
maxMessageSize(): number;
|
|
131
|
+
setBufferedAmountLowThreshold(newSize: number): void;
|
|
132
|
+
onOpen(cb: () => void): void;
|
|
133
|
+
onClosed(cb: () => void): void;
|
|
134
|
+
onError(cb: (err: string) => void): void;
|
|
135
|
+
onBufferedAmountLow(cb: () => void): void;
|
|
136
|
+
onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;
|
|
137
|
+
}
|
|
138
|
+
export const DataChannel: {
|
|
139
|
+
// DataChannel implementation
|
|
140
|
+
} = nodeDataChannel.DataChannel;
|
|
141
|
+
|
|
142
|
+
export interface PeerConnection {
|
|
143
|
+
close(): void;
|
|
144
|
+
setLocalDescription(type?: DescriptionType, init?: LocalDescriptionInit): void;
|
|
145
|
+
setRemoteDescription(sdp: string, type: DescriptionType): void;
|
|
146
|
+
localDescription(): { type: DescriptionType; sdp: string } | null;
|
|
147
|
+
remoteDescription(): { type: DescriptionType; sdp: string } | null;
|
|
148
|
+
remoteFingerprint(): CertificateFingerprint;
|
|
149
|
+
addRemoteCandidate(candidate: string, mid: string): void;
|
|
150
|
+
createDataChannel(label: string, config?: DataChannelInitConfig): DataChannel;
|
|
151
|
+
addTrack(media: Video | Audio): Track;
|
|
152
|
+
hasMedia(): boolean;
|
|
153
|
+
state(): RTCPeerConnectionState;
|
|
154
|
+
iceState(): RTCIceConnectionState;
|
|
155
|
+
signalingState(): RTCSignalingState;
|
|
156
|
+
gatheringState(): RTCIceGatheringState;
|
|
157
|
+
onLocalDescription(cb: (sdp: string, type: DescriptionType) => void): void;
|
|
158
|
+
onLocalCandidate(cb: (candidate: string, mid: string) => void): void;
|
|
159
|
+
onStateChange(cb: (state: string) => void): void;
|
|
160
|
+
onIceStateChange(cb: (state: string) => void): void;
|
|
161
|
+
onSignalingStateChange(cb: (state: string) => void): void;
|
|
162
|
+
onGatheringStateChange(cb: (state: string) => void): void;
|
|
163
|
+
onDataChannel(cb: (dc: DataChannel) => void): void;
|
|
164
|
+
onTrack(cb: (track: Track) => void): void;
|
|
165
|
+
bytesSent(): number;
|
|
166
|
+
bytesReceived(): number;
|
|
167
|
+
rtt(): number;
|
|
168
|
+
getSelectedCandidatePair(): {
|
|
169
|
+
local: SelectedCandidateInfo;
|
|
170
|
+
remote: SelectedCandidateInfo;
|
|
171
|
+
} | null;
|
|
172
|
+
maxDataChannelId(): number;
|
|
173
|
+
maxMessageSize(): number;
|
|
174
|
+
}
|
|
175
|
+
export const PeerConnection: {
|
|
176
|
+
new (peerName: string, config: RtcConfig): PeerConnection;
|
|
177
|
+
} = nodeDataChannel.PeerConnection;
|
|
178
|
+
|
|
179
|
+
export interface IceUdpMuxListener {
|
|
180
|
+
address?: string;
|
|
181
|
+
port: number;
|
|
182
|
+
stop(): void;
|
|
183
|
+
onUnhandledStunRequest(cb: (req: IceUdpMuxRequest) => void): void;
|
|
184
|
+
}
|
|
185
|
+
export const IceUdpMuxListener: {
|
|
186
|
+
new (port: number, address?: string): IceUdpMuxListener;
|
|
187
|
+
} = nodeDataChannel.IceUdpMuxListener;
|
|
188
|
+
|
|
189
|
+
export interface RtpPacketizationConfig {
|
|
190
|
+
playoutDelayId: number,
|
|
191
|
+
playoutDelayMin: number,
|
|
192
|
+
playoutDelayMax: number,
|
|
193
|
+
timestamp: number,
|
|
194
|
+
get clockRate(): number
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export const RtpPacketizationConfig: {
|
|
198
|
+
new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig
|
|
199
|
+
} = nodeDataChannel.RtpPacketizationConfig
|
|
200
|
+
|
|
201
|
+
export interface MediaHandler {
|
|
202
|
+
addToChain(handler: MediaHandler): void
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface RtcpReceivingSession extends MediaHandler {}
|
|
206
|
+
|
|
207
|
+
export const RtcpReceivingSession: {
|
|
208
|
+
new (): RtcpReceivingSession;
|
|
209
|
+
} = nodeDataChannel.RtcpReceivingSession;
|
|
210
|
+
|
|
211
|
+
export interface RtcpNackResponder extends MediaHandler {}
|
|
212
|
+
|
|
213
|
+
export const RtcpNackResponder: {
|
|
214
|
+
new (maxSize?: number): RtcpNackResponder
|
|
215
|
+
} = nodeDataChannel.RtcpNackResponder;
|
|
216
|
+
|
|
217
|
+
export interface RtcpSrReporter extends MediaHandler {
|
|
218
|
+
get rtpConfig(): RtpPacketizationConfig
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export const RtcpSrReporter: {
|
|
222
|
+
new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter
|
|
223
|
+
} = nodeDataChannel.RtcpSrReporter;
|
|
224
|
+
|
|
225
|
+
export interface RtpPacketizer extends MediaHandler {
|
|
226
|
+
get rtpConfig(): RtpPacketizationConfig
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export const RtpPacketizer: {
|
|
230
|
+
new (rtpConfig: RtpPacketizationConfig): RtpPacketizer
|
|
231
|
+
} = nodeDataChannel.RtpPacketizer;
|
|
232
|
+
|
|
233
|
+
export interface H264RtpPacketizer extends RtpPacketizer {}
|
|
234
|
+
|
|
235
|
+
export const H264RtpPacketizer: {
|
|
236
|
+
new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer
|
|
237
|
+
} = nodeDataChannel.H264RtpPacketizer
|
|
238
|
+
|
|
239
|
+
export interface H265RtpPacketizer extends RtpPacketizer {}
|
|
240
|
+
|
|
241
|
+
export const H265RtpPacketizer: {
|
|
242
|
+
new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer
|
|
243
|
+
} = nodeDataChannel.H265RtpPacketizer
|
|
244
|
+
|
|
245
|
+
export interface AV1RtpPacketizer extends RtpPacketizer {}
|
|
246
|
+
|
|
247
|
+
export const AV1RtpPacketizer: {
|
|
248
|
+
new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer
|
|
249
|
+
} = nodeDataChannel.AV1RtpPacketizer
|
|
250
|
+
|
|
251
|
+
export { WebSocketServer } from './websocket-server';
|
|
252
|
+
export { WebSocket } from './websocket';
|
|
253
|
+
|
|
254
|
+
export const DataChannelStream = _DataChannelStream;
|
|
255
|
+
|
|
256
|
+
export default {
|
|
257
|
+
initLogger,
|
|
258
|
+
cleanup,
|
|
259
|
+
preload,
|
|
260
|
+
setSctpSettings,
|
|
261
|
+
getLibraryVersion,
|
|
262
|
+
RtcpReceivingSession,
|
|
263
|
+
RtcpNackResponder,
|
|
264
|
+
RtcpSrReporter,
|
|
265
|
+
RtpPacketizationConfig,
|
|
266
|
+
RtpPacketizer,
|
|
267
|
+
H264RtpPacketizer,
|
|
268
|
+
H265RtpPacketizer,
|
|
269
|
+
AV1RtpPacketizer,
|
|
270
|
+
Track,
|
|
271
|
+
Video,
|
|
272
|
+
Audio,
|
|
273
|
+
DataChannel,
|
|
274
|
+
PeerConnection,
|
|
275
|
+
WebSocket,
|
|
276
|
+
WebSocketServer,
|
|
277
|
+
DataChannelStream,
|
|
278
|
+
IceUdpMuxListener,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
// Types
|
|
282
|
+
// https://github.com/murat-dogan/node-datachannel/issues/300
|
|
283
|
+
export * from './types';
|
package/src/lib/types.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
export interface Channel {
|
|
2
|
+
close(): void;
|
|
3
|
+
sendMessage(msg: string): boolean;
|
|
4
|
+
sendMessageBinary(buffer: Uint8Array): boolean;
|
|
5
|
+
isOpen(): boolean;
|
|
6
|
+
bufferedAmount(): number;
|
|
7
|
+
maxMessageSize(): number;
|
|
8
|
+
setBufferedAmountLowThreshold(newSize: number): void;
|
|
9
|
+
onOpen(cb: () => void): void;
|
|
10
|
+
onClosed(cb: () => void): void;
|
|
11
|
+
onError(cb: (err: string) => void): void;
|
|
12
|
+
onBufferedAmountLow(cb: () => void): void;
|
|
13
|
+
onMessage(cb: (msg: string | Buffer | ArrayBuffer) => void): void;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface WebSocketServerConfiguration {
|
|
17
|
+
port?: number; // default 8080
|
|
18
|
+
enableTls?: boolean; // default = false;
|
|
19
|
+
certificatePemFile?: string;
|
|
20
|
+
keyPemFile?: string;
|
|
21
|
+
keyPemPass?: string;
|
|
22
|
+
bindAddress?: string;
|
|
23
|
+
connectionTimeout?: number; // milliseconds
|
|
24
|
+
maxMessageSize?: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Enum in d.ts is tricky
|
|
28
|
+
export type LogLevel = 'Verbose' | 'Debug' | 'Info' | 'Warning' | 'Error' | 'Fatal';
|
|
29
|
+
|
|
30
|
+
// SCTP Settings
|
|
31
|
+
export interface SctpSettings {
|
|
32
|
+
recvBufferSize?: number;
|
|
33
|
+
sendBufferSize?: number;
|
|
34
|
+
maxChunksOnQueue?: number;
|
|
35
|
+
initialCongestionWindow?: number;
|
|
36
|
+
congestionControlModule?: number;
|
|
37
|
+
delayedSackTime?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Proxy Server
|
|
41
|
+
export type ProxyServerType = 'Socks5' | 'Http';
|
|
42
|
+
export interface ProxyServer {
|
|
43
|
+
type: ProxyServerType;
|
|
44
|
+
ip: string;
|
|
45
|
+
port: number;
|
|
46
|
+
username?: string;
|
|
47
|
+
password?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export type RelayType = 'TurnUdp' | 'TurnTcp' | 'TurnTls';
|
|
51
|
+
|
|
52
|
+
export interface IceServer {
|
|
53
|
+
hostname: string;
|
|
54
|
+
port: number;
|
|
55
|
+
username?: string;
|
|
56
|
+
password?: string;
|
|
57
|
+
relayType?: RelayType;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type TransportPolicy = 'all' | 'relay';
|
|
61
|
+
|
|
62
|
+
export interface RtcConfig {
|
|
63
|
+
iceServers: (string | IceServer)[];
|
|
64
|
+
proxyServer?: ProxyServer;
|
|
65
|
+
bindAddress?: string;
|
|
66
|
+
enableIceTcp?: boolean;
|
|
67
|
+
enableIceUdpMux?: boolean;
|
|
68
|
+
disableAutoNegotiation?: boolean;
|
|
69
|
+
forceMediaTransport?: boolean;
|
|
70
|
+
portRangeBegin?: number;
|
|
71
|
+
portRangeEnd?: number;
|
|
72
|
+
maxMessageSize?: number;
|
|
73
|
+
mtu?: number;
|
|
74
|
+
iceTransportPolicy?: TransportPolicy;
|
|
75
|
+
disableFingerprintVerification?: boolean;
|
|
76
|
+
disableAutoGathering?: boolean;
|
|
77
|
+
certificatePemFile?: string;
|
|
78
|
+
keyPemFile?: string;
|
|
79
|
+
keyPemPass?: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Lowercase to match the description type string from libdatachannel
|
|
83
|
+
export type DescriptionType = 'unspec' | 'offer' | 'answer' | 'pranswer' | 'rollback';
|
|
84
|
+
|
|
85
|
+
export type RTCSdpType = 'answer' | 'offer' | 'pranswer' | 'rollback';
|
|
86
|
+
|
|
87
|
+
export type RTCIceTransportState =
|
|
88
|
+
| 'checking'
|
|
89
|
+
| 'closed'
|
|
90
|
+
| 'completed'
|
|
91
|
+
| 'connected'
|
|
92
|
+
| 'disconnected'
|
|
93
|
+
| 'failed'
|
|
94
|
+
| 'new';
|
|
95
|
+
export type RTCPeerConnectionState =
|
|
96
|
+
| 'closed'
|
|
97
|
+
| 'connected'
|
|
98
|
+
| 'connecting'
|
|
99
|
+
| 'disconnected'
|
|
100
|
+
| 'failed'
|
|
101
|
+
| 'new';
|
|
102
|
+
export type RTCIceConnectionState =
|
|
103
|
+
| 'checking'
|
|
104
|
+
| 'closed'
|
|
105
|
+
| 'completed'
|
|
106
|
+
| 'connected'
|
|
107
|
+
| 'disconnected'
|
|
108
|
+
| 'failed'
|
|
109
|
+
| 'new';
|
|
110
|
+
export type RTCIceGathererState = 'complete' | 'gathering' | 'new';
|
|
111
|
+
export type RTCIceGatheringState = 'complete' | 'gathering' | 'new';
|
|
112
|
+
export type RTCSignalingState =
|
|
113
|
+
| 'closed'
|
|
114
|
+
| 'have-local-offer'
|
|
115
|
+
| 'have-local-pranswer'
|
|
116
|
+
| 'have-remote-offer'
|
|
117
|
+
| 'have-remote-pranswer'
|
|
118
|
+
| 'stable';
|
|
119
|
+
|
|
120
|
+
export interface LocalDescriptionInit {
|
|
121
|
+
iceUfrag?: string;
|
|
122
|
+
icePwd?: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface DataChannelInitConfig {
|
|
126
|
+
protocol?: string;
|
|
127
|
+
negotiated?: boolean;
|
|
128
|
+
id?: number;
|
|
129
|
+
unordered?: boolean; // Reliability
|
|
130
|
+
maxPacketLifeTime?: number; // Reliability
|
|
131
|
+
maxRetransmits?: number; // Reliability
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface CertificateFingerprint {
|
|
135
|
+
/**
|
|
136
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#value
|
|
137
|
+
*/
|
|
138
|
+
value: string;
|
|
139
|
+
/**
|
|
140
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/RTCCertificate/getFingerprints#algorithm
|
|
141
|
+
*/
|
|
142
|
+
algorithm: 'sha-1' | 'sha-224' | 'sha-256' | 'sha-384' | 'sha-512' | 'md5' | 'md2';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface SelectedCandidateInfo {
|
|
146
|
+
address: string;
|
|
147
|
+
port: number;
|
|
148
|
+
type: string;
|
|
149
|
+
transportType: string;
|
|
150
|
+
candidate: string;
|
|
151
|
+
mid: string;
|
|
152
|
+
priority: number;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Must be same as rtc enum class Direction
|
|
156
|
+
export type Direction = 'SendOnly' | 'RecvOnly' | 'SendRecv' | 'Inactive' | 'Unknown';
|
|
157
|
+
|
|
158
|
+
export interface IceUdpMuxRequest {
|
|
159
|
+
ufrag: string;
|
|
160
|
+
host: string;
|
|
161
|
+
port: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Same as rtc::NalUnit::Separator
|
|
165
|
+
export type NalUnitSeparator = 'Length' | 'ShortStartSequence' | 'LongStartSequence' | 'StartSequence';
|
|
166
|
+
|
|
167
|
+
// Same as rtc::AV1RtpPacketizer::Packetization
|
|
168
|
+
export type ObuPacketization = 'Obu' | 'TemporalUnit';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import nodeDataChannel from './node-datachannel';
|
|
3
|
+
import { WebSocketServerConfiguration } from './types';
|
|
4
|
+
import { WebSocket } from './websocket';
|
|
5
|
+
|
|
6
|
+
export class WebSocketServer extends EventEmitter {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
8
|
+
#server: any;
|
|
9
|
+
#clients: WebSocket[] = [];
|
|
10
|
+
|
|
11
|
+
constructor(options: WebSocketServerConfiguration) {
|
|
12
|
+
super();
|
|
13
|
+
this.#server = new nodeDataChannel.WebSocketServer(options);
|
|
14
|
+
|
|
15
|
+
this.#server.onClient((client) => {
|
|
16
|
+
this.emit('client', client);
|
|
17
|
+
this.#clients.push(client);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
port(): number {
|
|
22
|
+
return this.#server?.port() || 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
stop(): void {
|
|
26
|
+
this.#clients.forEach((client) => {
|
|
27
|
+
client?.close();
|
|
28
|
+
});
|
|
29
|
+
this.#server?.stop();
|
|
30
|
+
this.#server = null;
|
|
31
|
+
this.removeAllListeners();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onClient(cb: (clientSocket: WebSocket) => void): void {
|
|
35
|
+
if (this.#server) this.on('client', cb);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import nodeDataChannel from './node-datachannel';
|
|
2
|
+
import { Channel, WebSocketServerConfiguration } from './types';
|
|
3
|
+
|
|
4
|
+
export interface WebSocket extends Channel {
|
|
5
|
+
open(url: string): void;
|
|
6
|
+
forceClose(): void;
|
|
7
|
+
remoteAddress(): string | undefined;
|
|
8
|
+
path(): string | undefined;
|
|
9
|
+
|
|
10
|
+
// Channel implementation
|
|
11
|
+
close(): void;
|
|
12
|
+
sendMessage(msg: string): boolean;
|
|
13
|
+
sendMessageBinary(buffer: Uint8Array): boolean;
|
|
14
|
+
isOpen(): boolean;
|
|
15
|
+
bufferedAmount(): number;
|
|
16
|
+
maxMessageSize(): number;
|
|
17
|
+
setBufferedAmountLowThreshold(newSize: number): void;
|
|
18
|
+
onOpen(cb: () => void): void;
|
|
19
|
+
onClosed(cb: () => void): void;
|
|
20
|
+
onError(cb: (err: string) => void): void;
|
|
21
|
+
onBufferedAmountLow(cb: () => void): void;
|
|
22
|
+
onMessage(cb: (msg: string | Buffer) => void): void;
|
|
23
|
+
}
|
|
24
|
+
export const WebSocket: {
|
|
25
|
+
new (config?: WebSocketServerConfiguration): WebSocket;
|
|
26
|
+
} = nodeDataChannel.WebSocket;
|