178 lines
5.4 KiB
JavaScript
178 lines
5.4 KiB
JavaScript
|
var uuid = require('node-uuid');
|
||
|
|
||
|
module.exports = function(io, stunservers) {
|
||
|
|
||
|
var
|
||
|
activePeople = 0,
|
||
|
activeRooms = {};
|
||
|
|
||
|
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.on('setDetails', function (details) {
|
||
|
client.profile = {
|
||
|
username: details.username,
|
||
|
image: details.image
|
||
|
};
|
||
|
client.broadcast.emit('presence', client.profile);
|
||
|
});
|
||
|
|
||
|
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);
|
||
|
|
||
|
client.on('requestRoomCount', function(name) {
|
||
|
client.emit('room_count', {
|
||
|
room_id: name,
|
||
|
count: io.sockets.clients(name).length
|
||
|
});
|
||
|
});
|
||
|
|
||
|
client.on('requestActiveRooms', function() {
|
||
|
client.emit('rooms_count', Object.keys(activeRooms).length);
|
||
|
});
|
||
|
|
||
|
|
||
|
function removeFeed(type) {
|
||
|
if (client.room) {
|
||
|
io.sockets.in(client.room).emit('remove', {
|
||
|
id: client.id,
|
||
|
type: type
|
||
|
});
|
||
|
if (!type) {
|
||
|
client.leave(client.room);
|
||
|
}
|
||
|
io.sockets.emit('room_count', {
|
||
|
room_id: client.room,
|
||
|
count: io.sockets.clients(client.room).length
|
||
|
});
|
||
|
if (client.profile) {
|
||
|
client.broadcast.emit('vacated_room', {
|
||
|
room_id: client.room,
|
||
|
profile: client.profile
|
||
|
});
|
||
|
}
|
||
|
if (io.sockets.clients(client.room).length == 0) {
|
||
|
delete activeRooms[client.room];
|
||
|
io.sockets.emit('rooms_count', Object.keys(activeRooms).length);
|
||
|
}
|
||
|
if (!type) {
|
||
|
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);
|
||
|
io.sockets.emit('room_count', {
|
||
|
room_id: name,
|
||
|
count: io.sockets.clients(name).length
|
||
|
});
|
||
|
if (client.profile) {
|
||
|
client.broadcast.emit('presence_room', {
|
||
|
room_id: name,
|
||
|
profile: client.profile
|
||
|
});
|
||
|
}
|
||
|
io.sockets.clients(name).forEach(function (s) {
|
||
|
if (s.profile) {
|
||
|
client.emit('presence_room', {
|
||
|
room_id: name,
|
||
|
profile: s.profile
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
client.room = name;
|
||
|
activeRooms[name] = true;
|
||
|
io.sockets.emit('rooms_count', Object.keys(activeRooms).length);
|
||
|
}
|
||
|
|
||
|
// 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;
|
||
|
io.sockets.emit('users_count', activePeople);
|
||
|
if (client.profile) {
|
||
|
io.sockets.emit('vacated', client.profile);
|
||
|
}
|
||
|
});
|
||
|
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 || []);
|
||
|
|
||
|
client.emit('rooms_count', Object.keys(activeRooms).length);
|
||
|
io.sockets.emit('users_count', activePeople);
|
||
|
io.sockets.clients().forEach(function (socket) {
|
||
|
if (socket.id !== client.id && socket.profile) client.emit('presence', socket.profile);
|
||
|
});
|
||
|
});
|
||
|
};
|