-
Notifications
You must be signed in to change notification settings - Fork 2
rtc
A library for p2p communication over WebRTC DataChannel
WebRTC DataChannel requires a handshake in order to establish a peer to peer connection. This handshake is done with a combination of announce and signaling WebSocket servers.
This package only includes the front end implementation. Below is an example of a simple node WebSocket server.
DataChannelModule accepts a config that establishes the addresses of the WebSocket servers, a key and id. DataChannelModule can be injected in the root or a child module. Use forChild instead of forRoot when not injecting DataChannelModule in app.module.ts.
Think of the key as if it were a "room". It is the shared space the peers will communicate. The id of each peer must be unique. In this example, a uuid is assigned to each peer. When debug is set to true, the service will print messages in the console.
const uuid = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
};
const DataChannelConfig = {
key: 'openSeasame',
id: uuid(),
signalServer: `ws://localhost:5555`,
announceServer: `ws://localhost:5556`,
messageServer: `ws://localhost:5557`,
debug: true
}
@NgModule({
imports: [
DataChannelModule.forRoot(DataChannelConfig)
]
})
In your @Component, inject NgFxDataChannel. Once injected the service will send an announce signal. NgFxDataChannel exposes an emitter for listening to events, like when a RTCDataChannel is opened. Another emitter is exposed for subscribing to messages.
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { NgFxDataChannel } from '@ngfx/rtc';
public messages : string[] = new Array();
constructor(private _client: NgFxDataChannel,
private _ref: ChangeDetectorRef ) {}
...
this._client.emitter.subscribe((ev: NgFxDataChannelEvent) => {
if (ev.type === 'open') {
// check ev.payload for id of peer that just connected
}
});
this._client.messages.subscribe(msg => {
this.messages.push(msg.data.message);
this._ref.detectChanges();
});
NgFxDataChannel requires a WebSocket announce and signaling server for an initial handshake. You must bring your own WebSocket server for NgFxDataChannel to work. Below is an example that uses the npm package ws.
Each peer sends an announce message over WebSocket. If both peers can connect over RTCPeerConnection one peer will send an offer signal. The second peer answers back with an answer signal. Each peer signals ICECandidates back and forth until the DataChannel can be established.
const WebSocket = require('ws');
const signalport = 5555;
const wss = new WebSocket.Server({ port: signalport });
const announceport = 5556;
const wssa = new WebSocket.Server({ port: announceport });
wss.on('connection', function connection(ws) {
ws.on('error', (err) => {});
ws.on('message', function incoming(message) {
if (debug === true) console.log('SIGNAL: ', JSON.parse(JSON.stringify(message), null, 4));
//ws.send(JSON.stringify(message));
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
});
wssa.on('connection', function connection(ws) {
ws.on('error', (err) => {});
ws.on('message', function incoming(message) {
if (debug === true) console.log('ANNOUNCE: ', JSON.parse(JSON.stringify(message), null, 4));
//ws.send(JSON.stringify(message));
wssa.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
});