UNPKG

@tlaukkan/webrtc-signaling

Version:

WebRTC Signaling with Node.js WebSocket server.

107 lines (89 loc) 5.69 kB
const WebSocketServer = require('websocket').server; const http = require( 'http'); const signaling = require('./signaling-common'); const HandshakeResponse = signaling.HandshakeResponse; const RelayError = signaling.RelayError; const RelayErrorReason = signaling.RelayErrorReason; const sha256 = require('tiny-sha256'); exports.SignalingServer = class { constructor(host, port) { this.httpServer = http.createServer(function (request, response) { if (request.url.endsWith('/signaling-health-check')) { response.writeHead(200, {'Content-Type': 'text/plain'}); response.end(); } }); this.httpServer.listen(port, host, function () { }); const webSocketServer = new WebSocketServer({ httpServer: this.httpServer }); webSocketServer.idConnectionMap = new Map(); webSocketServer.connectionIdMap = new Map(); this.close = () => { console.log('signaling server closing ...'); webSocketServer.idConnectionMap.forEach((connection, id) => { console.log('signaling server disconnecting: ' + id + ' ' + connection.socket.remoteAddress + ':' + connection.socket.remotePort); connection.close(); }); this.httpServer.close(); console.log('signaling server closed.'); this.onClosed(); }; this.onClosed = () => { }; // WebSocket server webSocketServer.on('request', function (request) { console.log('signaling server connection request from ' + request.socket.remoteAddress + ':' + request.socket.remotePort); const connection = request.accept('webrtc-signaling', request.origin); connection.on('message', function (message) { if (message.type === 'utf8') { const messageObject = JSON.parse(message.utf8Data); if (messageObject.typeName === 'HandshakeRequest') { if (messageObject.email && messageObject.secret) { const id = sha256(messageObject.email.toString() + messageObject.secret.toString()); webSocketServer.idConnectionMap.set(id, connection); webSocketServer.connectionIdMap.set(connection, id); console.log('signaling server handshake success: ' + id + ' ' + messageObject.email + ' ' + connection.socket.remoteAddress + ':' + connection.socket.remotePort); connection.sendUTF(JSON.stringify(new HandshakeResponse(id))); } else { console.log('signaling server handshake failed: ' + connection.socket.remoteAddress + ':' + connection.socket.remotePort); connection.sendUTF(JSON.stringify(new HandshakeResponse(null, 'email and or secret is not defined in HandshakeRequest'))); } } if (messageObject.typeName === 'Message' && webSocketServer.connectionIdMap.has(connection)) { const sourceId = webSocketServer.connectionIdMap.get(connection); if (messageObject.sourceId && messageObject.sourceId === sourceId && messageObject.targetId && messageObject.contentType && messageObject.contentJson) { if (webSocketServer.idConnectionMap.has(messageObject.targetId)) { const targetConnection = webSocketServer.idConnectionMap.get(messageObject.targetId); const messageJson = JSON.stringify(messageObject); console.log('signaling server relayed message ' + messageObject.contentType + ' : ' + messageObject.contentJson + ' from ' + messageObject.sourceId + ' ' + connection.socket.remoteAddress + ':' + connection.socket.remotePort + ' to ' + messageObject.targetId + ' ' + targetConnection.socket.remoteAddress + ':' + targetConnection.socket.remotePort); targetConnection.sendUTF(messageJson); } else { connection.sendUTF(JSON.stringify(new RelayError(RelayErrorReason.TARGET_NOT_FOUND, messageObject))); } } else { connection.sendUTF(JSON.stringify(new RelayError(RelayErrorReason.MESSAGE_INVALID, messageObject))); } } // process WebSocket message } }); connection.on('close', function () { if (webSocketServer.connectionIdMap.has(connection)) { const id = webSocketServer.connectionIdMap.get(connection); console.log('signaling server disconnected: ' + id + ' ' + connection.socket.remoteAddress + ':' + connection.socket.remotePort); webSocketServer.connectionIdMap.delete(connection); webSocketServer.idConnectionMap.delete(id); } else { console.log('signaling server disconnection.' + connection.socket.remoteAddress + ':' + connection.socket.remotePort); } }); }); console.log('signaling server listening ws://' + host + ':' + port + '/'); } };