node-datachannel 0.12.0 → 0.20.0-alpha.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/.eslintignore +5 -1
- package/.eslintrc.json +27 -0
- package/.prettierrc +12 -0
- package/CMakeLists.txt +13 -13
- package/jest.config.ts +14 -0
- package/package.json +46 -43
- package/rollup.config.mjs +63 -0
- package/src/index.ts +10 -0
- package/{lib/datachannel-stream.js → src/lib/datachannel-stream.ts} +16 -11
- package/src/lib/index.ts +180 -0
- package/src/lib/node-datachannel.ts +13 -0
- package/src/lib/types.ts +126 -0
- package/{lib/websocket-server.js → src/lib/websocket-server.ts} +10 -8
- package/src/lib/websocket.ts +26 -0
- package/src/polyfill/Events.ts +33 -0
- package/src/polyfill/Exception.ts +37 -0
- package/src/polyfill/RTCCertificate.ts +17 -0
- package/{polyfill/RTCDataChannel.js → src/polyfill/RTCDataChannel.ts} +43 -40
- package/src/polyfill/RTCDtlsTransport.ts +47 -0
- package/src/polyfill/RTCError.ts +71 -0
- package/{polyfill/RTCIceCandidate.js → src/polyfill/RTCIceCandidate.ts} +35 -35
- package/{polyfill/RTCIceTransport.js → src/polyfill/RTCIceTransport.ts} +22 -20
- package/{polyfill/RTCPeerConnection.js → src/polyfill/RTCPeerConnection.ts} +128 -114
- package/{polyfill/RTCSctpTransport.js → src/polyfill/RTCSctpTransport.ts} +16 -14
- package/{polyfill/RTCSessionDescription.js → src/polyfill/RTCSessionDescription.ts} +7 -12
- package/{polyfill/index.js → src/polyfill/index.ts} +10 -10
- package/tsconfig.json +20 -13
- package/.eslintrc.cjs +0 -8
- package/.github/FUNDING.yml +0 -2
- package/.github/workflows/build-linux.yml +0 -109
- package/.github/workflows/build-mac-m1.yml +0 -38
- package/.github/workflows/build-mac-x64.yml +0 -40
- package/.github/workflows/build-win.yml +0 -74
- package/.github/workflows/lint.yml +0 -20
- package/.github/workflows/npm-publish-manual.yml +0 -23
- package/.prettierrc.cjs +0 -8
- package/build-containers/Dockerfile.alpine +0 -6
- package/build-containers/Dockerfile.debian +0 -7
- package/cmake/toolchain/ci.cmake +0 -23
- package/examples/client-server/README.md +0 -22
- package/examples/client-server/client-benchmark.js +0 -230
- package/examples/client-server/client-periodic.js +0 -189
- package/examples/client-server/client.js +0 -111
- package/examples/client-server/package-lock.json +0 -289
- package/examples/client-server/package.json +0 -16
- package/examples/client-server/signaling-server.js +0 -39
- package/examples/electron-demo/README.md +0 -58
- package/examples/electron-demo/forge.config.js +0 -49
- package/examples/electron-demo/package-lock.json +0 -15877
- package/examples/electron-demo/package.json +0 -44
- package/examples/electron-demo/src/index.css +0 -7
- package/examples/electron-demo/src/index.html +0 -29
- package/examples/electron-demo/src/main.js +0 -53
- package/examples/electron-demo/src/node-datachannel.js +0 -123
- package/examples/electron-demo/src/preload.js +0 -28
- package/examples/electron-demo/src/renderer.js +0 -58
- package/examples/electron-demo/webpack.main.config.js +0 -21
- package/examples/electron-demo/webpack.renderer.config.js +0 -13
- package/examples/electron-demo/webpack.rules.js +0 -35
- package/examples/media/README.md +0 -34
- package/examples/media/main.html +0 -45
- package/examples/media/media.js +0 -54
- package/examples/simple-peer-usage/main.js +0 -28
- package/examples/simple-peer-usage/package-lock.json +0 -317
- package/examples/simple-peer-usage/package.json +0 -16
- package/examples/websocket/websocket-client.js +0 -20
- package/examples/websocket/websocket-server.js +0 -22
- package/jest.config.cjs +0 -7
- package/lib/index.cjs +0 -194
- package/lib/index.d.cts +0 -300
- package/lib/index.d.ts +0 -300
- package/lib/index.js +0 -58
- package/lib/node-datachannel.js +0 -7
- package/polyfill/Events.d.ts +0 -9
- package/polyfill/Events.js +0 -29
- package/polyfill/Exception.js +0 -23
- package/polyfill/RTCCertificate.d.ts +0 -7
- package/polyfill/RTCCertificate.js +0 -17
- package/polyfill/RTCDataChannel.d.ts +0 -35
- package/polyfill/RTCDtlsTransport.d.ts +0 -10
- package/polyfill/RTCDtlsTransport.js +0 -47
- package/polyfill/RTCError.d.ts +0 -11
- package/polyfill/RTCError.js +0 -65
- package/polyfill/RTCIceCandidate.d.ts +0 -20
- package/polyfill/RTCIceTransport.d.ts +0 -18
- package/polyfill/RTCPeerConnection.d.ts +0 -62
- package/polyfill/RTCSctpTransport.d.ts +0 -10
- package/polyfill/RTCSessionDescription.d.ts +0 -8
- package/polyfill/index.cjs +0 -1333
- package/polyfill/index.d.cts +0 -37
- package/polyfill/index.d.ts +0 -37
- package/test/connectivity.js +0 -86
- package/test/jest-tests/basic.test.js +0 -37
- package/test/jest-tests/multiple-run.test.js +0 -73
- package/test/jest-tests/p2p.test.js +0 -99
- package/test/jest-tests/polyfill.test.js +0 -10
- package/test/jest-tests/streams.test.js +0 -48
- package/test/jest-tests/websocket.test.js +0 -69
- package/test/polyfill-connectivity.js +0 -89
- package/test/websockets.js +0 -50
- package/test/wpt-tests/README.md +0 -46
- package/test/wpt-tests/chrome-failed-tests.js +0 -42
- package/test/wpt-tests/index.js +0 -96
- package/test/wpt-tests/last-test-results.md +0 -301
- package/test/wpt-tests/package-lock.json +0 -1712
- package/test/wpt-tests/package.json +0 -19
- package/test/wpt-tests/wpt-test-list.js +0 -139
- package/test/wpt-tests/wpt.js +0 -131
- /package/src/{data-channel-wrapper.cpp → cpp/data-channel-wrapper.cpp} +0 -0
- /package/src/{data-channel-wrapper.h → cpp/data-channel-wrapper.h} +0 -0
- /package/src/{main.cpp → cpp/main.cpp} +0 -0
- /package/src/{media-audio-wrapper.cpp → cpp/media-audio-wrapper.cpp} +0 -0
- /package/src/{media-audio-wrapper.h → cpp/media-audio-wrapper.h} +0 -0
- /package/src/{media-direction.cpp → cpp/media-direction.cpp} +0 -0
- /package/src/{media-direction.h → cpp/media-direction.h} +0 -0
- /package/src/{media-rtcpreceivingsession-wrapper.cpp → cpp/media-rtcpreceivingsession-wrapper.cpp} +0 -0
- /package/src/{media-rtcpreceivingsession-wrapper.h → cpp/media-rtcpreceivingsession-wrapper.h} +0 -0
- /package/src/{media-track-wrapper.cpp → cpp/media-track-wrapper.cpp} +0 -0
- /package/src/{media-track-wrapper.h → cpp/media-track-wrapper.h} +0 -0
- /package/src/{media-video-wrapper.cpp → cpp/media-video-wrapper.cpp} +0 -0
- /package/src/{media-video-wrapper.h → cpp/media-video-wrapper.h} +0 -0
- /package/src/{peer-connection-wrapper.cpp → cpp/peer-connection-wrapper.cpp} +0 -0
- /package/src/{peer-connection-wrapper.h → cpp/peer-connection-wrapper.h} +0 -0
- /package/src/{rtc-wrapper.cpp → cpp/rtc-wrapper.cpp} +0 -0
- /package/src/{rtc-wrapper.h → cpp/rtc-wrapper.h} +0 -0
- /package/src/{thread-safe-callback.cpp → cpp/thread-safe-callback.cpp} +0 -0
- /package/src/{thread-safe-callback.h → cpp/thread-safe-callback.h} +0 -0
- /package/src/{web-socket-server-wrapper.cpp → cpp/web-socket-server-wrapper.cpp} +0 -0
- /package/src/{web-socket-server-wrapper.h → cpp/web-socket-server-wrapper.h} +0 -0
- /package/src/{web-socket-wrapper.cpp → cpp/web-socket-wrapper.cpp} +0 -0
- /package/src/{web-socket-wrapper.h → cpp/web-socket-wrapper.h} +0 -0
- /package/{polyfill → src/polyfill}/README.md +0 -0
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "electron-demo",
|
|
3
|
-
"productName": "electron-demo",
|
|
4
|
-
"version": "1.0.0",
|
|
5
|
-
"description": "My Electron application description",
|
|
6
|
-
"main": ".webpack/main",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"start": "electron-forge start",
|
|
9
|
-
"package": "electron-forge package",
|
|
10
|
-
"make": "electron-forge make",
|
|
11
|
-
"publish": "electron-forge publish",
|
|
12
|
-
"lint": "echo \"No linting configured\""
|
|
13
|
-
},
|
|
14
|
-
"keywords": [],
|
|
15
|
-
"author": {
|
|
16
|
-
"name": "Murat Dogan",
|
|
17
|
-
"email": "doganmurat@gmail.com"
|
|
18
|
-
},
|
|
19
|
-
"license": "MIT",
|
|
20
|
-
"devDependencies": {
|
|
21
|
-
"@electron-forge/cli": "^6.4.2",
|
|
22
|
-
"@electron-forge/maker-deb": "^6.4.2",
|
|
23
|
-
"@electron-forge/maker-rpm": "^6.4.2",
|
|
24
|
-
"@electron-forge/maker-squirrel": "^6.4.2",
|
|
25
|
-
"@electron-forge/maker-zip": "^6.4.2",
|
|
26
|
-
"@electron-forge/plugin-auto-unpack-natives": "^6.4.2",
|
|
27
|
-
"@electron-forge/plugin-webpack": "^6.4.2",
|
|
28
|
-
"@electron/rebuild": "^3.3.0",
|
|
29
|
-
"@vercel/webpack-asset-relocator-loader": "^1.7.3",
|
|
30
|
-
"copy-webpack-plugin": "^12.0.2",
|
|
31
|
-
"css-loader": "^6.8.1",
|
|
32
|
-
"electron": "26.2.4",
|
|
33
|
-
"node-loader": "^2.0.0",
|
|
34
|
-
"style-loader": "^3.3.3"
|
|
35
|
-
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"electron-squirrel-startup": "^1.0.0",
|
|
38
|
-
"node-datachannel": "^0.8.0"
|
|
39
|
-
},
|
|
40
|
-
"cmake-js": {
|
|
41
|
-
"runtime": "electron",
|
|
42
|
-
"runtimeVersion": "26.2.0"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<title>node-datachannel Demo</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
<h1>node-datachannel Demo</h1>
|
|
9
|
-
<h2>My ID: <span id="my-id"></span></h2>
|
|
10
|
-
<br />
|
|
11
|
-
<!-- Text box -->
|
|
12
|
-
<input id="remote-id" type="text" placeholder="Remote ID" />
|
|
13
|
-
<button onclick="connect()" id="connect">Connect</button>
|
|
14
|
-
<br />
|
|
15
|
-
<p>Status: <span id="state">disconnected</span></p>
|
|
16
|
-
<br />
|
|
17
|
-
<br />
|
|
18
|
-
<h2>Messages</h2>
|
|
19
|
-
<input id="new-message" type="text" placeholder="Message to Send" width="100px"/>
|
|
20
|
-
<button onclick="sendMessage()">Send</button>
|
|
21
|
-
<br />
|
|
22
|
-
<br />
|
|
23
|
-
<input id="sendRandom" type="checkbox" onclick="sendRandomMessage()">Send Random Messages</input> Every <input id="randomInterval" type="number" value="1000" min="1" step="100" /> ms
|
|
24
|
-
<br />
|
|
25
|
-
<br />
|
|
26
|
-
<textarea id="messages" rows="10" cols="80" readonly></textarea>
|
|
27
|
-
|
|
28
|
-
</body>
|
|
29
|
-
</html>
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
const { app, BrowserWindow } = require('electron');
|
|
3
|
-
|
|
4
|
-
const { run } = require('./node-datachannel.js');
|
|
5
|
-
|
|
6
|
-
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
|
7
|
-
if (require('electron-squirrel-startup')) {
|
|
8
|
-
app.quit();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const createWindow = () => {
|
|
12
|
-
// Create the browser window.
|
|
13
|
-
const mainWindow = new BrowserWindow({
|
|
14
|
-
width: 800,
|
|
15
|
-
height: 600,
|
|
16
|
-
webPreferences: {
|
|
17
|
-
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY,
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// and load the index.html of the app.
|
|
22
|
-
mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY);
|
|
23
|
-
|
|
24
|
-
// Open the DevTools.
|
|
25
|
-
mainWindow.webContents.openDevTools();
|
|
26
|
-
|
|
27
|
-
run(mainWindow);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// This method will be called when Electron has finished
|
|
31
|
-
// initialization and is ready to create browser windows.
|
|
32
|
-
// Some APIs can only be used after this event occurs.
|
|
33
|
-
app.on('ready', createWindow);
|
|
34
|
-
|
|
35
|
-
// Quit when all windows are closed, except on macOS. There, it's common
|
|
36
|
-
// for applications and their menu bar to stay active until the user quits
|
|
37
|
-
// explicitly with Cmd + Q.
|
|
38
|
-
app.on('window-all-closed', () => {
|
|
39
|
-
if (process.platform !== 'darwin') {
|
|
40
|
-
app.quit();
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
app.on('activate', () => {
|
|
45
|
-
// On OS X it's common to re-create a window in the app when the
|
|
46
|
-
// dock icon is clicked and there are no other windows open.
|
|
47
|
-
if (BrowserWindow.getAllWindows().length === 0) {
|
|
48
|
-
createWindow();
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// In this file you can include the rest of your app's specific main process
|
|
53
|
-
// code. You can also put them in separate files and import them here.
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
const nodeDataChannel = require('node-datachannel');
|
|
3
|
-
const WebSocket = require('ws');
|
|
4
|
-
const { ipcMain } = require('electron');
|
|
5
|
-
|
|
6
|
-
export function run(mainWindow) {
|
|
7
|
-
nodeDataChannel.initLogger('Debug');
|
|
8
|
-
nodeDataChannel.preload();
|
|
9
|
-
|
|
10
|
-
// My ID
|
|
11
|
-
let myId = getRandomString(4);
|
|
12
|
-
let _remoteId = '';
|
|
13
|
-
mainWindow.webContents.send('my-id', myId);
|
|
14
|
-
|
|
15
|
-
// PeerConnection Map
|
|
16
|
-
const pcMap = {};
|
|
17
|
-
const dcMap = {};
|
|
18
|
-
|
|
19
|
-
// Signaling Server
|
|
20
|
-
const WS_URL = process.env.WS_URL || 'ws://localhost:8000';
|
|
21
|
-
const ws = new WebSocket(WS_URL + '/' + myId, {
|
|
22
|
-
perMessageDeflate: false,
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
ws.on('open', () => {
|
|
26
|
-
console.log('WebSocket connected, signaling ready');
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
ws.on('error', (err) => {
|
|
30
|
-
console.log('WebSocket Error: ', err);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
ws.on('message', (msgStr) => {
|
|
34
|
-
let msg = JSON.parse(msgStr);
|
|
35
|
-
switch (msg.type) {
|
|
36
|
-
case 'offer':
|
|
37
|
-
_remoteId = msg.id;
|
|
38
|
-
mainWindow.webContents.send('connect', _remoteId);
|
|
39
|
-
createPeerConnection(msg.id);
|
|
40
|
-
pcMap[msg.id].setRemoteDescription(msg.description, msg.type);
|
|
41
|
-
break;
|
|
42
|
-
case 'answer':
|
|
43
|
-
pcMap[msg.id].setRemoteDescription(msg.description, msg.type);
|
|
44
|
-
break;
|
|
45
|
-
case 'candidate':
|
|
46
|
-
pcMap[msg.id].addRemoteCandidate(msg.candidate, msg.mid);
|
|
47
|
-
break;
|
|
48
|
-
|
|
49
|
-
default:
|
|
50
|
-
break;
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
ipcMain.on('connect', (e, remoteId) => {
|
|
55
|
-
_remoteId = remoteId;
|
|
56
|
-
createPeerConnection(remoteId);
|
|
57
|
-
dcMap[remoteId] = pcMap[remoteId].createDataChannel('chat');
|
|
58
|
-
dcMap[remoteId].onOpen(() => {
|
|
59
|
-
mainWindow.webContents.send('message', remoteId, '[DataChannel opened]');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
dcMap[remoteId].onMessage((msg) => {
|
|
63
|
-
console.log('Message from ' + remoteId + ' received:', msg);
|
|
64
|
-
// Add message to textarea
|
|
65
|
-
mainWindow.webContents.send('message', remoteId, msg);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
ipcMain.on('send-message', (e, remoteId, msg) => {
|
|
70
|
-
dcMap[remoteId].sendMessage(msg);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
let intervalref = null;
|
|
74
|
-
ipcMain.on('send-random-message', (e, enabled, interval) => {
|
|
75
|
-
if (intervalref) clearInterval(intervalref);
|
|
76
|
-
if (!enabled) return;
|
|
77
|
-
|
|
78
|
-
intervalref = setInterval(() => {
|
|
79
|
-
if (_remoteId && _remoteId.length > 2) {
|
|
80
|
-
let msg = getRandomString(10);
|
|
81
|
-
mainWindow.webContents.send('message', 'me', msg);
|
|
82
|
-
dcMap[_remoteId].sendMessage(msg);
|
|
83
|
-
}
|
|
84
|
-
}, interval);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
function createPeerConnection(peerId) {
|
|
88
|
-
// Create PeerConnection
|
|
89
|
-
let peerConnection = new nodeDataChannel.PeerConnection(myId, { iceServers: ['stun:stun.l.google.com:19302'] });
|
|
90
|
-
peerConnection.onStateChange((state) => {
|
|
91
|
-
console.log('State: ', state);
|
|
92
|
-
// set state value
|
|
93
|
-
mainWindow.webContents.send('state-update', state);
|
|
94
|
-
});
|
|
95
|
-
peerConnection.onGatheringStateChange((state) => {
|
|
96
|
-
console.log('GatheringState: ', state);
|
|
97
|
-
});
|
|
98
|
-
peerConnection.onLocalDescription((description, type) => {
|
|
99
|
-
ws.send(JSON.stringify({ id: peerId, type, description }));
|
|
100
|
-
});
|
|
101
|
-
peerConnection.onLocalCandidate((candidate, mid) => {
|
|
102
|
-
ws.send(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid }));
|
|
103
|
-
});
|
|
104
|
-
peerConnection.onDataChannel((dc) => {
|
|
105
|
-
console.log('DataChannel from ' + peerId + ' received with label "', dc.getLabel() + '"');
|
|
106
|
-
mainWindow.webContents.send('message', peerId, '[DataChannel opened]');
|
|
107
|
-
dcMap[peerId] = dc;
|
|
108
|
-
dc.onMessage((msg) => {
|
|
109
|
-
console.log('Message from ' + peerId + ' received:', msg);
|
|
110
|
-
// Add message to textarea
|
|
111
|
-
mainWindow.webContents.send('message', peerId, msg);
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
pcMap[peerId] = peerConnection;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function getRandomString(length) {
|
|
119
|
-
return Math.random()
|
|
120
|
-
.toString(36)
|
|
121
|
-
.substring(2, 2 + length);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
// See the Electron documentation for details on how to use preload scripts:
|
|
3
|
-
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
|
|
4
|
-
const { contextBridge, ipcRenderer } = require('electron');
|
|
5
|
-
|
|
6
|
-
contextBridge.exposeInMainWorld('electron', {
|
|
7
|
-
connect: (remoteId) => ipcRenderer.send('connect', remoteId),
|
|
8
|
-
sendMessage: (remoteId, msg) => ipcRenderer.send('send-message', remoteId, msg),
|
|
9
|
-
sendRandomMessage: (enabled, interval) => ipcRenderer.send('send-random-message', enabled, interval),
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
ipcRenderer.on('my-id', (e, myId) => {
|
|
13
|
-
document.getElementById('my-id').innerHTML = myId;
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
ipcRenderer.on('message', (e, remoteId, msg) => {
|
|
17
|
-
document.getElementById('messages').value += remoteId + '> ' + msg + '\n';
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
ipcRenderer.on('connect', (e, remoteId) => {
|
|
21
|
-
document.getElementById('connect').disabled = true;
|
|
22
|
-
document.getElementById('remote-id').disabled = true;
|
|
23
|
-
document.getElementById('remote-id').value = remoteId;
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
ipcRenderer.on('state-update', (e, state) => {
|
|
27
|
-
document.getElementById('state').innerHTML = state;
|
|
28
|
-
});
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file will automatically be loaded by webpack and run in the "renderer" context.
|
|
3
|
-
* To learn more about the differences between the "main" and the "renderer" context in
|
|
4
|
-
* Electron, visit:
|
|
5
|
-
*
|
|
6
|
-
* https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes
|
|
7
|
-
*
|
|
8
|
-
* By default, Node.js integration in this file is disabled. When enabling Node.js integration
|
|
9
|
-
* in a renderer process, please be aware of potential security implications. You can read
|
|
10
|
-
* more about security risks here:
|
|
11
|
-
*
|
|
12
|
-
* https://electronjs.org/docs/tutorial/security
|
|
13
|
-
*
|
|
14
|
-
* To enable Node.js integration in this file, open up `main.js` and enable the `nodeIntegration`
|
|
15
|
-
* flag:
|
|
16
|
-
*
|
|
17
|
-
* ```
|
|
18
|
-
* // Create the browser window.
|
|
19
|
-
* mainWindow = new BrowserWindow({
|
|
20
|
-
* width: 800,
|
|
21
|
-
* height: 600,
|
|
22
|
-
* webPreferences: {
|
|
23
|
-
* nodeIntegration: true
|
|
24
|
-
* }
|
|
25
|
-
* });
|
|
26
|
-
* ```
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
import './index.css';
|
|
30
|
-
|
|
31
|
-
window.connect = () => {
|
|
32
|
-
const remoteId = document.getElementById('remote-id').value;
|
|
33
|
-
if (remoteId && remoteId.length > 2) {
|
|
34
|
-
// disable connect button
|
|
35
|
-
document.getElementById('connect').disabled = true;
|
|
36
|
-
document.getElementById('remote-id').disabled = true;
|
|
37
|
-
|
|
38
|
-
window.electron.connect(remoteId);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
window.sendMessage = () => {
|
|
43
|
-
const remoteId = document.getElementById('remote-id').value;
|
|
44
|
-
if (remoteId && remoteId.length > 2) {
|
|
45
|
-
let msg = document.getElementById('new-message').value;
|
|
46
|
-
if (msg && msg.length > 0) {
|
|
47
|
-
document.getElementById('new-message').value = '';
|
|
48
|
-
document.getElementById('messages').value += 'me> ' + msg + '\n';
|
|
49
|
-
window.electron.sendMessage(remoteId, msg);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
window.sendRandomMessage = () => {
|
|
55
|
-
let enabled = document.getElementById('sendRandom').checked;
|
|
56
|
-
let interval = document.getElementById('randomInterval').value;
|
|
57
|
-
window.electron.sendRandomMessage(enabled, interval);
|
|
58
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const CopyPlugin = require('copy-webpack-plugin');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
/**
|
|
5
|
-
* This is the main entry point for your application, it's the first file
|
|
6
|
-
* that runs in the main process.
|
|
7
|
-
*/
|
|
8
|
-
entry: './src/main.js',
|
|
9
|
-
// Put your normal webpack config below here
|
|
10
|
-
module: {
|
|
11
|
-
rules: require('./webpack.rules'),
|
|
12
|
-
},
|
|
13
|
-
externals: {
|
|
14
|
-
'node-datachannel': 'node-datachannel',
|
|
15
|
-
},
|
|
16
|
-
plugins: [
|
|
17
|
-
new CopyPlugin({
|
|
18
|
-
patterns: [{ from: 'node_modules/node-datachannel', to: 'node_modules/node-datachannel' }],
|
|
19
|
-
}),
|
|
20
|
-
],
|
|
21
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module.exports = [
|
|
2
|
-
// Add support for native node modules
|
|
3
|
-
{
|
|
4
|
-
// We're specifying native_modules in the test because the asset relocator loader generates a
|
|
5
|
-
// "fake" .node file which is really a cjs file.
|
|
6
|
-
test: /native_modules[/\\].+\.node$/,
|
|
7
|
-
use: 'node-loader',
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
test: /[/\\]node_modules[/\\].+\.(m?js|node)$/,
|
|
11
|
-
parser: { amd: false },
|
|
12
|
-
use: {
|
|
13
|
-
loader: '@vercel/webpack-asset-relocator-loader',
|
|
14
|
-
options: {
|
|
15
|
-
outputAssetBase: 'native_modules',
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
// Put your webpack loader rules in this array. This is where you would put
|
|
20
|
-
// your ts-loader configuration for instance:
|
|
21
|
-
/**
|
|
22
|
-
* Typescript Example:
|
|
23
|
-
*
|
|
24
|
-
* {
|
|
25
|
-
* test: /\.tsx?$/,
|
|
26
|
-
* exclude: /(node_modules|.webpack)/,
|
|
27
|
-
* loaders: [{
|
|
28
|
-
* loader: 'ts-loader',
|
|
29
|
-
* options: {
|
|
30
|
-
* transpileOnly: true
|
|
31
|
-
* }
|
|
32
|
-
* }]
|
|
33
|
-
* }
|
|
34
|
-
*/
|
|
35
|
-
];
|
package/examples/media/README.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# media Example
|
|
2
|
-
|
|
3
|
-
## Example Webcam from Browser to Port 5000
|
|
4
|
-
|
|
5
|
-
This is an example copy/paste demo to send your webcam from your browser and out port 5000 through the demo application.
|
|
6
|
-
|
|
7
|
-
## How to use
|
|
8
|
-
|
|
9
|
-
Open main.html in your browser (you must open it either as HTTPS or as a domain of http://localhost).
|
|
10
|
-
|
|
11
|
-
Start the application and copy it's offer into the text box of the web page.
|
|
12
|
-
|
|
13
|
-
Copy the answer of the webpage back into the application.
|
|
14
|
-
|
|
15
|
-
You will now see RTP traffic on `localhost:5000` of the computer that the application is running on.
|
|
16
|
-
|
|
17
|
-
Use the following gstreamer demo pipeline to display the traffic
|
|
18
|
-
(you might need to wave your hand in front of your camera to force an I-frame).
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
$ gst-launch-1.0 udpsrc address=127.0.0.1 port=5000 caps="application/x-rtp" ! queue ! rtph264depay ! video/x-h264,stream-format=byte-stream ! queue ! avdec_h264 ! queue ! autovideosink
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
For saving the stream to a file, use the following pipeline (mp4):
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
gst-launch-1.0 -e udpsrc address=127.0.0.1 port=5000 caps="application/x-rtp" ! queue ! rtph264depay ! h264parse ! mp4mux ! filesink location=out.mp4
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Requirements
|
|
31
|
-
|
|
32
|
-
- GStreamer 1.0
|
|
33
|
-
- gstreamer1.0-libav (sudo apt-get install gstreamer1.0-libav)
|
|
34
|
-
- h264enc (sudo apt-get install h264enc)
|
package/examples/media/main.html
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<title>libdatachannel media example</title>
|
|
6
|
-
</head>
|
|
7
|
-
<body>
|
|
8
|
-
|
|
9
|
-
<p>Please enter the offer provided to you by the application: </p>
|
|
10
|
-
<textarea cols="50" rows="50"></textarea>
|
|
11
|
-
<button>Submit</button>
|
|
12
|
-
|
|
13
|
-
<script>
|
|
14
|
-
document.querySelector('button').addEventListener('click', async () => {
|
|
15
|
-
let offer = JSON.parse(document.querySelector('textarea').value);
|
|
16
|
-
rtc = new RTCPeerConnection({
|
|
17
|
-
// Recommended for libdatachannel
|
|
18
|
-
bundlePolicy: "max-bundle",
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
rtc.onicegatheringstatechange = (state) => {
|
|
22
|
-
if (rtc.iceGatheringState === 'complete') {
|
|
23
|
-
// We only want to provide an answer once all of our candidates have been added to the SDP.
|
|
24
|
-
let answer = rtc.localDescription;
|
|
25
|
-
document.querySelector('textarea').value = JSON.stringify({"type": answer.type, sdp: answer.sdp});
|
|
26
|
-
document.querySelector('p').value = 'Please paste the answer in the application.';
|
|
27
|
-
alert('Please paste the answer in the application.');
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
await rtc.setRemoteDescription(offer);
|
|
31
|
-
|
|
32
|
-
let media = await navigator.mediaDevices.getUserMedia({
|
|
33
|
-
video: {
|
|
34
|
-
width: 1280,
|
|
35
|
-
height: 720
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
media.getTracks().forEach(track => rtc.addTrack(track, media));
|
|
39
|
-
let answer = await rtc.createAnswer();
|
|
40
|
-
await rtc.setLocalDescription(answer);
|
|
41
|
-
})
|
|
42
|
-
</script>
|
|
43
|
-
|
|
44
|
-
</body>
|
|
45
|
-
</html>
|
package/examples/media/media.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import readline from 'readline';
|
|
2
|
-
import nodeDataChannel from '../../lib/index.js';
|
|
3
|
-
import dgram from 'dgram';
|
|
4
|
-
|
|
5
|
-
var client = dgram.createSocket('udp4');
|
|
6
|
-
|
|
7
|
-
// Read Line Interface
|
|
8
|
-
const rl = readline.createInterface({
|
|
9
|
-
input: process.stdin,
|
|
10
|
-
output: process.stdout,
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
// Init Logger
|
|
14
|
-
nodeDataChannel.initLogger('Debug');
|
|
15
|
-
|
|
16
|
-
let peerConnection = new nodeDataChannel.PeerConnection('pc', { iceServers: [] });
|
|
17
|
-
|
|
18
|
-
peerConnection.onStateChange((state) => {
|
|
19
|
-
console.log('State: ', state);
|
|
20
|
-
});
|
|
21
|
-
peerConnection.onGatheringStateChange((state) => {
|
|
22
|
-
// console.log('GatheringState: ', state);
|
|
23
|
-
|
|
24
|
-
if (state == 'complete') {
|
|
25
|
-
let desc = peerConnection.localDescription();
|
|
26
|
-
console.log('');
|
|
27
|
-
console.log('## Please copy the offer below to the web page:');
|
|
28
|
-
console.log(JSON.stringify(desc));
|
|
29
|
-
console.log('\n\n');
|
|
30
|
-
console.log('## Expect RTP video traffic on localhost:5000');
|
|
31
|
-
rl.question('## Please copy/paste the answer provided by the browser: \n', (sdp) => {
|
|
32
|
-
let sdpObj = JSON.parse(sdp);
|
|
33
|
-
peerConnection.setRemoteDescription(sdpObj.sdp, sdpObj.type);
|
|
34
|
-
console.log(track.isOpen());
|
|
35
|
-
rl.close();
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
let video = new nodeDataChannel.Video('video', 'RecvOnly');
|
|
41
|
-
video.addH264Codec(96);
|
|
42
|
-
video.setBitrate(3000);
|
|
43
|
-
|
|
44
|
-
let track = peerConnection.addTrack(video);
|
|
45
|
-
let session = new nodeDataChannel.RtcpReceivingSession();
|
|
46
|
-
|
|
47
|
-
track.setMediaHandler(session);
|
|
48
|
-
track.onMessage((msg) => {
|
|
49
|
-
client.send(msg, 5000, '127.0.0.1', (err, n) => {
|
|
50
|
-
if (err) console.log(err, n);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
peerConnection.setLocalDescription();
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import Peer from 'simple-peer';
|
|
2
|
-
import nodeDatachannelPolyfill from '../../polyfill/index.js';
|
|
3
|
-
import nodeDataChannel from '../../lib/index.js';
|
|
4
|
-
|
|
5
|
-
nodeDataChannel.initLogger('Info');
|
|
6
|
-
|
|
7
|
-
var peer1 = new Peer({ initiator: true, wrtc: nodeDatachannelPolyfill });
|
|
8
|
-
var peer2 = new Peer({ wrtc: nodeDatachannelPolyfill });
|
|
9
|
-
|
|
10
|
-
peer1.on('signal', (data) => {
|
|
11
|
-
// when peer1 has signaling data, give it to peer2 somehow
|
|
12
|
-
peer2.signal(data);
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
peer2.on('signal', (data) => {
|
|
16
|
-
// when peer2 has signaling data, give it to peer1 somehow
|
|
17
|
-
peer1.signal(data);
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
peer1.on('connect', () => {
|
|
21
|
-
// wait for 'connect' event before using the data channel
|
|
22
|
-
peer1.send('hey peer2, how is it going?');
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
peer2.on('data', (data) => {
|
|
26
|
-
// got a data channel message
|
|
27
|
-
console.log('got a message from peer1: ' + data);
|
|
28
|
-
});
|