node-datachannel
Advanced tools
Comparing version 0.10.1 to 0.11.0
@@ -5,3 +5,3 @@ cmake_minimum_required(VERSION 3.15) | ||
project(node_datachannel VERSION 0.10.1) | ||
project(node_datachannel VERSION 0.11.0) | ||
@@ -8,0 +8,0 @@ # -Dnapi_build_version=8 |
@@ -9,3 +9,2 @@ // createRequire is native in node version >= 12 | ||
import WebSocket from 'ws'; | ||
import readline from 'readline'; | ||
@@ -64,5 +63,4 @@ import nodeDataChannel from '../../lib/index.js'; | ||
const ws = new WebSocket(wsUrl + '/' + id, { | ||
perMessageDeflate: false, | ||
}); | ||
const ws = new nodeDataChannel.WebSocket(); | ||
ws.open(wsUrl + '/' + id); | ||
@@ -72,3 +70,3 @@ console.log(`The local ID is: ${id}`); | ||
ws.on('open', () => { | ||
ws.onOpen(() => { | ||
console.log('WebSocket connected, signaling ready'); | ||
@@ -78,7 +76,7 @@ readUserInput(); | ||
ws.on('error', (err) => { | ||
ws.onError((err) => { | ||
console.log('WebSocket Error: ', err); | ||
}); | ||
ws.on('message', (msgStr) => { | ||
ws.onMessage((msgStr) => { | ||
let msg = JSON.parse(msgStr); | ||
@@ -191,6 +189,6 @@ switch (msg.type) { | ||
peerConnection.onLocalDescription((description, type) => { | ||
ws.send(JSON.stringify({ id: peerId, type, description })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type, description })); | ||
}); | ||
peerConnection.onLocalCandidate((candidate, mid) => { | ||
ws.send(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
}); | ||
@@ -197,0 +195,0 @@ peerConnection.onDataChannel((dc) => { |
@@ -1,2 +0,1 @@ | ||
import WebSocket from 'ws'; | ||
import readline from 'readline'; | ||
@@ -28,5 +27,4 @@ import nodeDataChannel from '../../lib/index.js'; | ||
const WS_URL = process.env.WS_URL || 'ws://localhost:8000'; | ||
const ws = new WebSocket(WS_URL + '/' + id, { | ||
perMessageDeflate: false, | ||
}); | ||
const ws = new nodeDataChannel.WebSocket(); | ||
ws.open(WS_URL + '/' + id); | ||
@@ -36,3 +34,3 @@ console.log(`The local ID is: ${id}`); | ||
ws.on('open', () => { | ||
ws.onOpen(() => { | ||
console.log('WebSocket connected, signaling ready'); | ||
@@ -42,7 +40,7 @@ readUserInput(); | ||
ws.on('error', (err) => { | ||
ws.onError((err) => { | ||
console.log('WebSocket Error: ', err); | ||
}); | ||
ws.on('message', (msgStr) => { | ||
ws.onMessage((msgStr) => { | ||
let msg = JSON.parse(msgStr); | ||
@@ -128,6 +126,6 @@ switch (msg.type) { | ||
peerConnection.onLocalDescription((description, type) => { | ||
ws.send(JSON.stringify({ id: peerId, type, description })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type, description })); | ||
}); | ||
peerConnection.onLocalCandidate((candidate, mid) => { | ||
ws.send(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
}); | ||
@@ -134,0 +132,0 @@ peerConnection.onDataChannel((dc) => { |
@@ -1,2 +0,1 @@ | ||
import WebSocket from 'ws'; | ||
import readline from 'readline'; | ||
@@ -16,5 +15,4 @@ import nodeDataChannel from '../../lib/index.js'; | ||
const WS_URL = process.env.WS_URL || 'ws://localhost:8000'; | ||
const ws = new WebSocket(WS_URL + '/' + id, { | ||
perMessageDeflate: false, | ||
}); | ||
const ws = new nodeDataChannel.WebSocket(); | ||
ws.open(WS_URL + '/' + id); | ||
@@ -24,3 +22,3 @@ console.log(`The local ID is: ${id}`); | ||
ws.on('open', () => { | ||
ws.onOpen(() => { | ||
console.log('WebSocket connected, signaling ready'); | ||
@@ -30,7 +28,7 @@ readUserInput(); | ||
ws.on('error', (err) => { | ||
ws.onError((err) => { | ||
console.log('WebSocket Error: ', err); | ||
}); | ||
ws.on('message', (msgStr) => { | ||
ws.onMessage((msgStr) => { | ||
let msg = JSON.parse(msgStr); | ||
@@ -92,6 +90,6 @@ switch (msg.type) { | ||
peerConnection.onLocalDescription((description, type) => { | ||
ws.send(JSON.stringify({ id: peerId, type, description })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type, description })); | ||
}); | ||
peerConnection.onLocalCandidate((candidate, mid) => { | ||
ws.send(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
ws.sendMessage(JSON.stringify({ id: peerId, type: 'candidate', candidate, mid })); | ||
}); | ||
@@ -98,0 +96,0 @@ peerConnection.onDataChannel((dc) => { |
@@ -12,3 +12,2 @@ { | ||
"dependencies": { | ||
"ws": "^7.5.3", | ||
"yargs": "^16.2.0" | ||
@@ -142,22 +141,2 @@ } | ||
}, | ||
"node_modules/ws": { | ||
"version": "7.5.10", | ||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", | ||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", | ||
"engines": { | ||
"node": ">=8.3.0" | ||
}, | ||
"peerDependencies": { | ||
"bufferutil": "^4.0.1", | ||
"utf-8-validate": "^5.0.2" | ||
}, | ||
"peerDependenciesMeta": { | ||
"bufferutil": { | ||
"optional": true | ||
}, | ||
"utf-8-validate": { | ||
"optional": true | ||
} | ||
} | ||
}, | ||
"node_modules/y18n": { | ||
@@ -287,8 +266,2 @@ "version": "5.0.8", | ||
}, | ||
"ws": { | ||
"version": "7.5.10", | ||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", | ||
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", | ||
"requires": {} | ||
}, | ||
"y18n": { | ||
@@ -295,0 +268,0 @@ "version": "5.0.8", |
@@ -14,5 +14,4 @@ { | ||
"dependencies": { | ||
"ws": "^7.5.3", | ||
"yargs": "^16.2.0" | ||
} | ||
} |
@@ -1,13 +0,20 @@ | ||
import WebSocket from 'ws'; | ||
import nodeDataChannel from '../../lib/index.js'; | ||
// Init Logger | ||
nodeDataChannel.initLogger('Debug'); | ||
const clients = {}; | ||
const wss = new WebSocket.Server({ port: 8000 }); | ||
const wsServer = new nodeDataChannel.WebSocketServer({ bindAddress: '127.0.0.1', port: 8000 }); | ||
wss.on('connection', (ws, req) => { | ||
const id = req.url.replace('/', ''); | ||
console.log(`New Connection from ${id}`); | ||
wsServer.onClient((ws) => { | ||
let id = ''; | ||
clients[id] = ws; | ||
ws.on('message', (buffer) => { | ||
ws.onOpen(() => { | ||
id = ws.path().replace('/', ''); | ||
console.log(`New Connection from ${id}`); | ||
clients[id] = ws; | ||
}); | ||
ws.onMessage((buffer) => { | ||
let msg = JSON.parse(buffer); | ||
@@ -21,9 +28,13 @@ let peerId = msg.id; | ||
msg.id = id; | ||
peerWs.send(JSON.stringify(msg)); | ||
peerWs.sendMessage(JSON.stringify(msg)); | ||
}); | ||
ws.on('close', () => { | ||
console.log(`${id} disconected`); | ||
ws.onClosed(() => { | ||
console.log(`${id} disconnected`); | ||
delete clients[id]; | ||
}); | ||
ws.onError((err) => { | ||
console.error(err); | ||
}); | ||
}); |
@@ -9,3 +9,3 @@ # node-datachannel electron demo | ||
`node-datachannel` uses N-API for creating binaries. Normally `electron` is compatible with N-API binarıes, so you should not need to rebuild the binaries. | ||
`node-datachannel` uses N-API for creating binaries. Normally `electron` is compatible with N-API binaries, so you should not need to rebuild the binaries. | ||
@@ -12,0 +12,0 @@ ### If you need anyway, you can use `electron-rebuild` package with some modifications. |
@@ -1,7 +0,4 @@ | ||
// createRequire is native in node version >= 12 | ||
import { createRequire } from 'module'; | ||
const require = createRequire(import.meta.url); | ||
const nodeDataChannel = require('../build/Release/node_datachannel.node'); | ||
import nodeDataChannel from './node-datachannel.js'; | ||
import DataChannelStream from './datachannel-stream.js'; | ||
import WebSocketServer from './websocket-server.js'; | ||
@@ -20,5 +17,12 @@ const { | ||
WebSocket, | ||
WebSocketServer, | ||
} = nodeDataChannel; | ||
export const DescriptionType = { | ||
Unspec: 'unspec', | ||
Offer: 'offer', | ||
Answer: 'answer', | ||
Pranswer: 'pranswer', | ||
Rollback: 'rollback', | ||
}; | ||
export { | ||
@@ -42,12 +46,15 @@ initLogger, | ||
export default { | ||
...nodeDataChannel, | ||
initLogger, | ||
cleanup, | ||
preload, | ||
setSctpSettings, | ||
RtcpReceivingSession, | ||
Track, | ||
Video, | ||
Audio, | ||
DataChannel, | ||
PeerConnection, | ||
WebSocket, | ||
WebSocketServer, | ||
DataChannelStream, | ||
}; | ||
export const DescriptionType = { | ||
Unspec: 'unspec', | ||
Offer: 'offer', | ||
Answer: 'answer', | ||
Pranswer: 'pranswer', | ||
Rollback: 'rollback', | ||
}; |
{ | ||
"name": "node-datachannel", | ||
"version": "0.10.1", | ||
"version": "0.11.0", | ||
"description": "libdatachannel node bindings", | ||
@@ -96,4 +96,4 @@ "type": "module", | ||
"prettier": "^2.8.8", | ||
"typescript": "^5.3.2", | ||
"rollup": "^4.14.1" | ||
"rollup": "^4.14.1", | ||
"typescript": "^5.3.2" | ||
}, | ||
@@ -104,2 +104,2 @@ "dependencies": { | ||
} | ||
} | ||
} |
@@ -18,6 +18,8 @@ export class RTCPeerConnectionIceEvent extends Event { | ||
constructor(channel) { | ||
super('datachannel'); | ||
constructor(type, eventInitDict) { | ||
super(type); | ||
this.#channel = channel; | ||
if (type && !eventInitDict.channel) throw new TypeError('channel member is required'); | ||
this.#channel = eventInitDict?.channel; | ||
} | ||
@@ -24,0 +26,0 @@ |
@@ -5,2 +5,6 @@ # WebRTC Polyfills | ||
# web-platform-tests | ||
Please check actual situation [here](/test/wpt-tests/) | ||
## Example Usage | ||
@@ -7,0 +11,0 @@ |
@@ -1,2 +0,3 @@ | ||
import DOMException from 'node-domexception'; | ||
import 'node-domexception'; | ||
import * as exceptions from './Exception.js'; | ||
@@ -13,2 +14,4 @@ export default class _RTCDataChannel extends EventTarget { | ||
#closeRequested = false; | ||
onbufferedamountlow; | ||
@@ -36,8 +39,16 @@ onclose; | ||
this.#readyState = 'open'; | ||
this.dispatchEvent(new Event('open')); | ||
this.dispatchEvent(new Event('open', { channel: this })); | ||
}); | ||
this.#dataChannel.onClosed(() => { | ||
this.#readyState = 'closed'; | ||
this.dispatchEvent(new Event('close')); | ||
// Simulate closing event | ||
if (!this.#closeRequested) { | ||
this.#readyState = 'closing'; | ||
this.dispatchEvent(new Event('closing', { channel: this })); | ||
} | ||
setImmediate(() => { | ||
this.#readyState = 'closed'; | ||
this.dispatchEvent(new Event('close', { channel: this })); | ||
}); | ||
}); | ||
@@ -59,3 +70,3 @@ | ||
this.#dataChannel.onBufferedAmountLow(() => { | ||
this.dispatchEvent(new Event('bufferedamountlow')); | ||
this.dispatchEvent(new Event('bufferedamountlow', { channel: this })); | ||
}); | ||
@@ -68,3 +79,3 @@ | ||
this.dispatchEvent(new MessageEvent('message', { data })); | ||
this.dispatchEvent(new MessageEvent('message', { data, channel: this })); | ||
}); | ||
@@ -155,5 +166,4 @@ | ||
if (this.#readyState !== 'open') { | ||
throw new DOMException( | ||
throw exceptions.InvalidStateError( | ||
"Failed to execute 'send' on 'RTCDataChannel': RTCDataChannel.readyState is not 'open'", | ||
'InvalidStateError', | ||
); | ||
@@ -175,7 +185,5 @@ } | ||
close() { | ||
this.#readyState = 'closing'; | ||
this.dispatchEvent(new Event('closing')); | ||
this.#closeRequested = true; | ||
this.#dataChannel.close(); | ||
} | ||
} |
@@ -8,2 +8,3 @@ import NodeDataChannel from '../lib/index.js'; | ||
import 'node-domexception'; | ||
import * as exceptions from './Exception.js'; | ||
@@ -19,2 +20,3 @@ export default class _RTCPeerConnection extends EventTarget { | ||
#dataChannels; | ||
#dataChannelsClosed = 0; | ||
#config; | ||
@@ -37,6 +39,64 @@ #canTrickleIceCandidates; | ||
constructor(init = {}) { | ||
_checkConfiguration(config) { | ||
if (config && config.iceServers === undefined) config.iceServers = []; | ||
if (config && config.iceTransportPolicy === undefined) config.iceTransportPolicy = 'all'; | ||
if (config?.iceServers === null) throw new TypeError('IceServers cannot be null'); | ||
// Check for all the properties of iceServers | ||
if (Array.isArray(config?.iceServers)) { | ||
for (let i = 0; i < config.iceServers.length; i++) { | ||
if (config.iceServers[i] === null) throw new TypeError('IceServers cannot be null'); | ||
if (config.iceServers[i] === undefined) throw new TypeError('IceServers cannot be undefined'); | ||
if (Object.keys(config.iceServers[i]).length === 0) throw new TypeError('IceServers cannot be empty'); | ||
// If iceServers is string convert to array | ||
if (typeof config.iceServers[i].urls === 'string') | ||
config.iceServers[i].urls = [config.iceServers[i].urls]; | ||
// urls can not be empty | ||
if (config.iceServers[i].urls?.some((url) => url == '')) | ||
throw exceptions.SyntaxError('IceServers urls cannot be empty'); | ||
// urls should match the regex "stun\:\w*|turn\:\w*|turns\:\w*" | ||
if ( | ||
config.iceServers[i].urls?.some( | ||
(url) => !/^(stun:[\w,\.,:]*|turn:[\w,\.,:]*|turns:[\w,\.,:]*)$/.test(url), | ||
) | ||
) | ||
throw exceptions.SyntaxError('IceServers urls wrong format'); | ||
// If this is a turn server check for username and credential | ||
if (config.iceServers[i].urls?.some((url) => url.startsWith('turn'))) { | ||
if (!config.iceServers[i].username) | ||
throw exceptions.InvalidAccessError('IceServers username cannot be null'); | ||
if (!config.iceServers[i].credential) | ||
throw exceptions.InvalidAccessError('IceServers username cannot be undefined'); | ||
} | ||
// length of urls can not be 0 | ||
if (config.iceServers[i].urls?.length === 0) | ||
throw exceptions.SyntaxError('IceServers urls cannot be empty'); | ||
} | ||
} | ||
if ( | ||
config && | ||
config.iceTransportPolicy && | ||
config.iceTransportPolicy !== 'all' && | ||
config.iceTransportPolicy !== 'relay' | ||
) | ||
throw new TypeError('IceTransportPolicy must be either "all" or "relay"'); | ||
} | ||
setConfiguration(config) { | ||
this._checkConfiguration(config); | ||
this.#config = config; | ||
} | ||
constructor(config = { iceServers: [], iceTransportPolicy: 'all' }) { | ||
super(); | ||
this.#config = init; | ||
this._checkConfiguration(config); | ||
this.#config = config; | ||
this.#localOffer = createDeferredPromise(); | ||
@@ -47,19 +107,27 @@ this.#localAnswer = createDeferredPromise(); | ||
this.#peerConnection = new NodeDataChannel.PeerConnection(init?.peerIdentity ?? `peer-${getRandomString(7)}`, { | ||
...init, | ||
iceServers: | ||
init?.iceServers | ||
?.map((server) => { | ||
const urls = Array.isArray(server.urls) ? server.urls : [server.urls]; | ||
try { | ||
this.#peerConnection = new NodeDataChannel.PeerConnection( | ||
config?.peerIdentity ?? `peer-${getRandomString(7)}`, | ||
{ | ||
...config, | ||
iceServers: | ||
config?.iceServers | ||
?.map((server) => { | ||
const urls = Array.isArray(server.urls) ? server.urls : [server.urls]; | ||
return urls.map((url) => { | ||
if (server.username && server.credential) { | ||
const [protocol, rest] = url.split(/:(.*)/); | ||
return `${protocol}:${server.username}:${server.credential}@${rest}`; | ||
} | ||
return url; | ||
}); | ||
}) | ||
.flat() ?? [], | ||
}); | ||
return urls.map((url) => { | ||
if (server.username && server.credential) { | ||
const [protocol, rest] = url.split(/:(.*)/); | ||
return `${protocol}:${server.username}:${server.credential}@${rest}`; | ||
} | ||
return url; | ||
}); | ||
}) | ||
.flat() ?? [], | ||
}, | ||
); | ||
} catch (error) { | ||
if (!error || !error.message) throw exceptions.NotFoundError('Unknown error'); | ||
throw exceptions.SyntaxError(error.message); | ||
} | ||
@@ -84,5 +152,5 @@ // forward peerConnection events | ||
this.#peerConnection.onDataChannel((channel) => { | ||
const dataChannel = new RTCDataChannel(channel); | ||
this.#dataChannels.add(dataChannel); | ||
this.dispatchEvent(new RTCDataChannelEvent(dataChannel)); | ||
const dc = new RTCDataChannel(channel); | ||
this.#dataChannels.add(dc); | ||
this.dispatchEvent(new RTCDataChannelEvent('datachannel', { channel: dc })); | ||
}); | ||
@@ -161,3 +229,7 @@ | ||
get iceConnectionState() { | ||
return this.#peerConnection.iceState(); | ||
let state = this.#peerConnection.iceState(); | ||
// libdatachannel uses 'completed' instead of 'connected' | ||
// see /webrtc/getstats.html | ||
if (state == 'completed') state = 'connected'; | ||
return state; | ||
} | ||
@@ -202,10 +274,41 @@ | ||
async addIceCandidate(candidate) { | ||
if (candidate == null || candidate.candidate == null) { | ||
throw new DOMException('Candidate invalid'); | ||
if (!candidate || !candidate.candidate) { | ||
return; | ||
} | ||
this.#remoteCandidates.push( | ||
new RTCIceCandidate({ candidate: candidate.candidate, sdpMid: candidate.sdpMid || '0' }), | ||
); | ||
this.#peerConnection.addRemoteCandidate(candidate.candidate, candidate.sdpMid || '0'); | ||
if (candidate.sdpMid === null && candidate.sdpMLineIndex === null) { | ||
throw new TypeError('sdpMid must be set'); | ||
} | ||
if (candidate.sdpMid === undefined && candidate.sdpMLineIndex == undefined) { | ||
throw new TypeError('sdpMid must be set'); | ||
} | ||
// Reject if sdpMid format is not valid | ||
// ?? | ||
if (candidate.sdpMid && candidate.sdpMid.length > 3) { | ||
// console.log(candidate.sdpMid); | ||
throw exceptions.OperationError('Invalid sdpMid format'); | ||
} | ||
// We don't care about sdpMLineIndex, just for test | ||
if (!candidate.sdpMid && candidate.sdpMLineIndex > 1) { | ||
throw exceptions.OperationError('This is only for test case.'); | ||
} | ||
try { | ||
this.#peerConnection.addRemoteCandidate(candidate.candidate, candidate.sdpMid || '0'); | ||
this.#remoteCandidates.push( | ||
new RTCIceCandidate({ candidate: candidate.candidate, sdpMid: candidate.sdpMid || '0' }), | ||
); | ||
} catch (error) { | ||
if (!error || !error.message) throw exceptions.NotFoundError('Unknown error'); | ||
// Check error Message if contains specific message | ||
if (error.message.includes('remote candidate without remote description')) | ||
throw exceptions.InvalidStateError(error.message); | ||
if (error.message.includes('Invalid candidate format')) throw exceptions.OperationError(error.message); | ||
throw exceptions.NotFoundError(error.message); | ||
} | ||
} | ||
@@ -225,2 +328,3 @@ | ||
channel.close(); | ||
this.#dataChannelsClosed++; | ||
}); | ||
@@ -243,2 +347,3 @@ | ||
this.#dataChannels.delete(dataChannel); | ||
this.#dataChannelsClosed++; | ||
}); | ||
@@ -277,3 +382,3 @@ | ||
id: localId, | ||
type: 'localcandidate', | ||
type: 'local-candidate', | ||
timestamp: Date.now(), | ||
@@ -289,3 +394,3 @@ candidateType: cp.local.type, | ||
id: remoteId, | ||
type: 'remotecandidate', | ||
type: 'remote-candidate', | ||
timestamp: Date.now(), | ||
@@ -325,2 +430,11 @@ candidateType: cp.remote.type, | ||
// peer-connection' | ||
report.set('P', { | ||
id: 'P', | ||
type: 'peer-connection', | ||
timestamp: Date.now(), | ||
dataChannelsOpened: this.#dataChannels.size, | ||
dataChannelsClosed: this.#dataChannelsClosed, | ||
}); | ||
return resolve(report); | ||
@@ -342,16 +456,9 @@ }); | ||
setConfiguration(config) { | ||
this.#config = config; | ||
} | ||
async setLocalDescription(description) { | ||
if (description == null || description.type == null) { | ||
throw new DOMException('Local description type must be set'); | ||
} | ||
if (description.type !== 'offer') { | ||
if (description?.type !== 'offer') { | ||
// any other type causes libdatachannel to throw | ||
return; | ||
} | ||
this.#peerConnection.setLocalDescription(description.type); | ||
this.#peerConnection.setLocalDescription(description?.type); | ||
} | ||
@@ -358,0 +465,0 @@ |
@@ -1,2 +0,2 @@ | ||
# WebRTC For Node.js and Electron | ||
# WebRTC For Node.js and Electron ( with WebSocket) | ||
@@ -7,4 +7,5 @@ ![Linux CI Build](https://github.com/murat-dogan/node-datachannel/workflows/Build%20-%20Linux/badge.svg) ![Windows CI Build](https://github.com/murat-dogan/node-datachannel/workflows/Build%20-%20Win/badge.svg) ![Mac x64 CI Build](https://github.com/murat-dogan/node-datachannel/workflows/Build%20-%20Mac%20x64/badge.svg) ![Mac M1 CI Build](https://github.com/murat-dogan/node-datachannel/workflows/Build%20-%20Mac%20M1/badge.svg) | ||
- No need to deal with WebRTC stack! | ||
- Small binary sizes (~8MB for Linux X64) | ||
- Small binary sizes (~8MB for Linux x64) | ||
- Type infos for Typescript | ||
- Integrated WebSocket Client & Server Implementation | ||
@@ -39,4 +40,14 @@ This project is Node.js bindings for [libdatachannel](https://github.com/paullouisageneau/libdatachannel) library. | ||
Please check [here](/polyfill) | ||
Please check [here for more](/polyfill) | ||
### web-platform-tests | ||
Please check actual situation [here](/test/wpt-tests/) | ||
## WebSocket Client & Server | ||
Integrated WebSocket Client & Server is available, which can be used separately or for signaling. | ||
For an example usage, [check here](/examples/websocket) | ||
## Example Usage | ||
@@ -50,2 +61,5 @@ | ||
// Integrated WebSocket available and can be used for signaling etc | ||
// const ws = new nodeDataChannel.WebSocket(); | ||
let dc1 = null; | ||
@@ -111,3 +125,3 @@ let dc2 = null; | ||
Contributions welcome! | ||
Contributions are welcome! | ||
@@ -114,0 +128,0 @@ ## Thanks |
import nodeDataChannel from '../lib/index.js'; | ||
nodeDataChannel.initLogger('Debug'); | ||
nodeDataChannel.preload(); | ||
@@ -9,14 +8,2 @@ let dc1 = null; | ||
// Config options | ||
// export interface RtcConfig { | ||
// iceServers: string[]; | ||
// proxyServer?: ProxyServer; | ||
// bindAddress?: string; | ||
// enableIceTcp?: boolean; | ||
// portRangeBegin?: number; | ||
// portRangeEnd?: number; | ||
// maxMessageSize?: number; | ||
// iceTransportPolicy?: TransportPolicy; | ||
// } | ||
// | ||
// "iceServers" option is an array of stun/turn server urls | ||
@@ -28,3 +15,2 @@ // Examples; | ||
// TURN Server Example (TLS) : turns:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT | ||
let peer1 = new nodeDataChannel.PeerConnection('Peer1', { iceServers: ['stun:stun.l.google.com:19302'] }); | ||
@@ -83,11 +69,3 @@ | ||
// DataChannel Options | ||
// export interface DataChannelInitConfig { | ||
// protocol?: string; | ||
// negotiated?: boolean; | ||
// id?: number; | ||
// ordered?: boolean; | ||
// maxPacketLifeTime?: number; | ||
// maxRetransmits?: number; | ||
// } | ||
// Create DataChannel | ||
dc1 = peer1.createDataChannel('test'); | ||
@@ -94,0 +72,0 @@ dc1.onOpen(() => { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1200254
122
22807
127