var uuid = require('node-uuid'); module.exports = function(io, stunservers) { var activePeople = 0; function describeRoom(name) { var clients = io.sockets.clients(name); var result = { clients: {} }; clients.forEach(function (client) { result.clients[client.id] = client.resources; }); return result; } function safeCb(cb) { if (typeof cb === 'function') { return cb; } else { return function () {}; } } io.sockets.on('connection', function (client) { activePeople += 1; 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.sockets.sockets[details.to]; if (!otherClient) return; details.from = client.id; otherClient.emit('message', details); }); client.on('shareScreen', function () { client.resources.screen = true; }); client.on('unshareScreen', function (type) { client.resources.screen = false; removeFeed('screen'); }); client.on('join', join); function removeFeed(type) { if (client.room) { io.sockets.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; // leave any existing rooms removeFeed(); safeCb(cb)(null, describeRoom(name)); client.join(name); client.room = name; } // we don't want to pass "leave" directly because the // event type string of "socket end" gets passed too. client.on('disconnect', function () { removeFeed(); activePeople -= 1; }); client.on('leave', function () { removeFeed(); }); client.on('create', function (name, cb) { if (arguments.length == 2) { cb = (typeof cb == 'function') ? cb : function () {}; name = name || uuid(); } else { cb = name; name = uuid(); } // check if exists if (io.sockets.clients(name).length) { safeCb(cb)('taken'); } else { join(name); safeCb(cb)(null, name); } }); // tell client about stun and turn servers and generate nonces client.emit('stunservers', stunservers || []); }); };