Commit 9fe0cd64 authored by Moritz Langenstein's avatar Moritz Langenstein
Browse files

(ml5717) Pre-built signalbuddy to dist/

parent baa85f58
......@@ -4,7 +4,6 @@ node_modules
ecosystem.config.js
Dockerfile
.drone.yml
dist
.jshintignore
.jshintrc
yarn-error.log
'use strict';
var _getconfig = require('getconfig');
var _getconfig2 = _interopRequireDefault(_getconfig);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _os = require('os');
var _os2 = _interopRequireDefault(_os);
var _stickySession = require('sticky-session');
var _stickySession2 = _interopRequireDefault(_stickySession);
var _farmhash = require('farmhash');
var _farmhash2 = _interopRequireDefault(_farmhash);
var _net = require('net');
var _net2 = _interopRequireDefault(_net);
var _cluster = require('cluster');
var _cluster2 = _interopRequireDefault(_cluster);
var _http = require('http');
var _http2 = _interopRequireDefault(_http);
var _https = require('https');
var _https2 = _interopRequireDefault(_https);
var _sockets = require('./sockets');
var _sockets2 = _interopRequireDefault(_sockets);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var port = parseInt(process.env.PORT || _getconfig2.default.server.port, 10);
var redisEndpoint = process.env.REDIS_ENDPOINT || _getconfig2.default.redis.endpoint;
var redisPort = process.env.REDIS_PORT || _getconfig2.default.redis.port;
var numProcesses = _os2.default.cpus().length;
if (_cluster2.default.isMaster) {
var workers = [];
var spawn = function spawn(i) {
workers[i] = _cluster2.default.fork();
// Persistence
workers[i].on('exit', function (code, signal) {
console.log('Worker ' + i + ' exited with signal ' + signal);
console.log('Respawning worker', i);
spawn(i);
});
};
for (var i = 0; i < numProcesses; i += 1) {
console.log('Starting worker ' + (i + 1));
spawn(i);
}
var workerIndex = function workerIndex(ip, len) {
return (// Farmhash is the fastest and works with IPv6, too
_farmhash2.default.fingerprint32(ip) % len
);
};
// Create the outside facing server listening on our port.
var masterServer = _net2.default.createServer({ pauseOnConnect: true }, function (connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var worker = workers[workerIndex(connection.remoteAddress, numProcesses)];
worker.send('sticky-session:connection', connection);
}).listen(port);
console.log('Listening at ' + (_getconfig2.default.server.secure ? 'https' : 'http') + '://' + (process.env.NODE_ENV === 'production' ? '0.0.0.0' : 'localhost') + ':' + port + '/');
} else {
var serverHandler = function serverHandler(req, res) {
if (req.url === '/healthcheck') {
console.log(Date.now(), 'healthcheck');
res.writeHead(200);
res.end();
return;
}
res.writeHead(404);
res.end('worker: ' + _cluster2.default.worker.id);
};
var server = null;
// Create an http(s) server instance to that socket.io can listen to
if (_getconfig2.default.server.secure) {
server = _https2.default.Server({
key: _fs2.default.readFileSync(process.env.PRIV_KEY || _getconfig2.default.server.key),
cert: _fs2.default.readFileSync(process.env.CERT || _getconfig2.default.server.cert),
passphrase: _getconfig2.default.server.password
}, serverHandler);
} else {
server = _http2.default.Server(serverHandler);
}
if (!_stickySession2.default.listen(server, port)) {
// Master
} else {
// Worker
}
server.listen(0);
(0, _sockets2.default)(server, Object.assign({ redisEndpoint: redisEndpoint, redisPort: redisPort }, _getconfig2.default));
if (_getconfig2.default.uid) process.setuid(_getconfig2.default.uid);
process.on('message', function (message, connection) {
if (message !== 'sticky-session:connection') {
return;
}
// Emulate a connection event on the server by emitting the
// event with the connection the master sent us.
server.emit('connection', connection);
connection.resume();
});
}
\ No newline at end of file
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _arguments = arguments;
var _socket = require('socket.io');
var _socket2 = _interopRequireDefault(_socket);
var _v = require('uuid/v4');
var _v2 = _interopRequireDefault(_v);
var _crypto = require('crypto');
var _crypto2 = _interopRequireDefault(_crypto);
var _socket3 = require('socket.io-redis');
var _socket4 = _interopRequireDefault(_socket3);
var _util = require('./util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = function (server, config) {
var io = _socket2.default.listen(server);
io.adapter((0, _socket4.default)({ host: config.redis.host, port: config.redis.port }));
io.on('connection', function (client) {
client.resources = {
screen: false,
video: true,
audio: false
};
// pass a message to another id
client.on('message', function (details) {
if (!details) return;
var otherClient = io.to(details.to);
if (!otherClient) return;
details.from = client.id;
otherClient.emit('message', details);
});
client.on('join', join);
client.on('getClients', getClients);
client.on('getClientCount', getClientCount);
client.on('getMyId', getClientId);
function removeFeed(type) {
if (client.room) {
io.in(client.room).emit('remove', {
id: client.id,
type: type
});
if (!type) {
client.leave(client.room);
client.room = undefined;
}
}
}
function join(name, cb) {
// sanity check
if (typeof name !== 'string') return;
// check if maximum number of clients reached
if (config.rooms && config.rooms.maxClients > 0) {
getClientCount(name).then(function (count) {
if (count > config.rooms.maxClients) {
removeFeed();
}
});
}
// leave any existing rooms
removeFeed();
getClients(name, function (err, clients) {
return (0, _util.safeCb)(cb)(err, Object.assign({}, { you: client.id }, clients));
});
client.join(name);
client.room = name;
}
function getClients(roomName, callback) {
describeRoom(roomName).then(function (description) {
var obj = { clients: {} };
description.forEach(function (k) {
obj.clients[k] = client.resources;
});
(0, _util.safeCb)(callback)(null, obj);
}).catch(function (err) {
return (0, _util.safeCb)(callback)(err, null);
});
}
function getClientCount(roomName, callback) {
clientsInRoom(roomName).then(function (num) {
if (roomName) (0, _util.safeCb)(callback)(num);
});
}
function getClientId(callback) {
(0, _util.safeCb)(callback)(client.id);
}
// we don't want to pass "leave" directly because the
// event type string of "socket end" gets passed too.
client.on('disconnect', function () {
removeFeed();
});
client.on('leave', function () {
removeFeed();
});
client.on('create', function (name, cb) {
if (_arguments.length === 2) {
cb = typeof cb === 'function' ? cb : function () {};
name = name || (0, _v2.default)();
} else {
cb = name;
name = (0, _v2.default)();
}
// check if exists
io.in(name).clients(function (err, clients) {
if (clients && clients.length) {
(0, _util.safeCb)(cb)('taken');
} else {
join(name);
(0, _util.safeCb)(cb)(null, name);
}
});
});
/*
client.on('trace', (data) => {
// console.log('trace', JSON.stringify([data.type, data.session, data.prefix, data.peer, data.time, data.value]));
});
*/
// tell client about stun and turn servers and generate nonces
client.emit('stunservers', config.stunservers || []);
// create shared secret nonces for TURN authentication
// the process is described in draft-uberti-behave-turn-rest
var credentials = [];
// allow selectively vending turn credentials based on origin.
var origin = client.handshake.headers.origin;
if (!config.turnorigins || config.turnorigins.includes(origin)) {
config.turnservers.forEach(function (server) {
var hmac = _crypto2.default.createHmac('sha1', server.secret);
// default to 86400 seconds timeout unless specified
var username = '' + (Math.floor(new Date().getTime() / 1000) + parseInt(server.expiry || 86400, 10));
hmac.update(username);
credentials.push({
username: username,
credential: hmac.digest('base64'),
urls: server.urls || server.url
});
});
}
client.emit('turnservers', credentials);
});
function describeRoom(roomName) {
return new Promise(function (resolve, reject) {
io.in(roomName).clients(function (err, clients) {
if (err) {
reject(err);
return;
}
resolve(clients);
});
});
}
function clientsInRoom(roomName) {
return new Promise(function (resolve, reject) {
io.in(roomName).clients(function (err, clients) {
if (err) {
reject(err);
return;
}
resolve(clients.length);
});
});
}
};
\ No newline at end of file
'use strict';
function safeCb(cb) {
if (typeof cb === 'function') {
return cb;
}
return function () {};
}
module.exports = {
safeCb: safeCb
};
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment