solving problems with rooms handling

parent 983dc73b
/** /**
* This hook is used for managing the rooms IDs. * This hook is used for managing the rooms IDs.
* Every room created should call one of this functions in order * Every room created should call one of this functions in order
* to obtain an ID. * to obtain an ID.
* Each socket connection can refers to just one ui and two possible rooms:
* one for a student and one for a supervisor.
* @type {Object} * @type {Object}
*/ */
var socketRooms = {}; // {socketId => [roomId, ...]} var sockets = {}; // {socket : {stu_room: room, sup_room: room, ui: ui}}
var roomPeers = {}; // {roomId: {pcb_count, pdb_count}} var rooms = {}; // {room: [socket, ...]}
module.exports = function roomsHook (sails) { module.exports = function roomsHook (sails) {
return { return {
/** /**************************************************************************
* Returns room information * Notifies to all the room's subscribers about the number of different
* @param {Socket} socket * connections by UI:
* @return {return} room information * pdb_count (number of connections to the given room from Pictogram Web)
{ * pcb_count (number of connections to the given room from Pictogram Communicator/Supervisor)
id: room_id,
ui: 'PCB'|'PDB' // type of user interface
}
*/ */
getRoom: function (socket) { notifyRoom: function(room) {
return socketRooms[sails.sockets.getId(socket)]; // Let's count number of connections per room and per UI
var counter = {'PCB': 0, 'PDB': 0};
//console.log('notifyRoom (' + room + ')---->\n' + JSON.stringify(sockets) + '\n' + JSON.stringify(rooms));
async.each( // for each socket in the room
rooms[room],
(socket, cb) => {
if (sockets[socket])
counter[sockets[socket].ui] += 1;
cb();
},
(err) => {
if (err)
sails.debug.log("Error when notifying room " + JSON.stringify(err));
else {
// Broadcast data to room's peers
sails.hooks.events.broadcastEvent(
room,
sails.hooks.events.roomSubscribersChange({
'room': room,
'pdb_count': counter['PDB'],
'pcb_count': counter['PCB']
})
);
}
}
);
}, },
/** /**************************************************************************
* Special function that subscribes a socket to a given room. * Special function that subscribes a socket to a given room.
* This creates the connection and logs to debug with this format: * This creates the connection and logs to debug with this format:
* *
...@@ -42,51 +66,49 @@ module.exports = function roomsHook (sails) { ...@@ -42,51 +66,49 @@ module.exports = function roomsHook (sails) {
* @param {UI} ui Type of UI that sends the suscription ('PDB' or 'PCB') * @param {UI} ui Type of UI that sends the suscription ('PDB' or 'PCB')
*/ */
subscribeToRoom: function (room, socket, ui) { subscribeToRoom: function (room, socket, ui) {
//console.log('subscribeToRoom (' + room + ', ' + socket.id + ', ' + ui + ')---->\n' + JSON.stringify(sockets) + '\n' + JSON.stringify(rooms));
sails.log.debug('"websocketSubscribe":', JSON.stringify({ sails.log.debug('"websocketSubscribe":', JSON.stringify({
room: room, room: room,
socket: socket.id, socket: socket.id,
ui: ui ui: ui
})); }));
var roomType = room.search("student") < 0 ? 'sup_room' : 'stu_room';
sails.sockets.join(socket, room, function () { sails.sockets.join(socket, room, function () {
sails.io.sockets.in(room).clients(function(error, ids) { sails.io.sockets.in(room).clients(function(error, ids) {
if (!error) { if (error) return;
var socket_id = sails.sockets.getId(socket);
if (sockets[socket.id]) { // socket already subscribed to a room
// remove old info
var old_room = sockets[socket.id][roomType];
if (rooms[old_room]) {
var pos = rooms[old_room].indexOf(socket.id);
if (pos >= 0)
rooms[old_room].splice(pos, 1);
sails.hooks.rooms.notifyRoom(old_room);
}
}
// append to socketRooms // set new info
if (!socketRooms[socket_id]) if (!sockets[socket.id])
socketRooms[socket_id] = [{room: room, ui: ui}]; sockets[socket.id] = {};
sockets[socket.id].ui = ui;
sockets[socket.id][roomType] = room;
if (!rooms[room])
rooms[room] = [socket.id];
else else
socketRooms[socket_id].push({room: room, ui: ui}); rooms[room].push(socket.id);
// append/updated room peer counters sails.hooks.rooms.notifyRoom(room);
if (!roomPeers[room]) {
roomPeers[room] = {
pcb_count: ui == 'PCB' ? 1 : 0,
pdb_count: ui == 'PDB' ? 1 : 0
};
} else {
roomPeers[room].pcb_count += ui == 'PCB' ? 1 : 0;
roomPeers[room].pdb_count += ui == 'PDB' ? 1 : 0;
}
// broadcast data
sails.hooks.events.broadcastEvent(
room,
sails.hooks.events.roomSubscribersChange({
'room': room,
'pdb_count': roomPeers[room].pdb_count,
'pcb_count': roomPeers[room].pcb_count
})
);
}
}); });
}); });
}, },
/** /**************************************************************************
* Special function that unsubscribes a socket from a given room. * Special function that unsubscribes a socket from a given room.
* This remotes the connection and logs to debug with this format: * This remotes the connection and logs to debug with this format:
* *
...@@ -101,51 +123,36 @@ module.exports = function roomsHook (sails) { ...@@ -101,51 +123,36 @@ module.exports = function roomsHook (sails) {
* @param {Socket} socket Socket removed from the subscription * @param {Socket} socket Socket removed from the subscription
*/ */
unsubscribeFromRoom: function (room, socket) { unsubscribeFromRoom: function (room, socket) {
sails.log.debug('"websocketUnsubscribe":', JSON.stringify({
room: room,
socket: socket.id
}));
sails.sockets.leave(socket, room, function () {
sails.io.sockets.in(room).clients(function(error, ids) {
if (!error) {
// look for the room the socket is subscribed to and remove it
if (socketRooms[sails.sockets.getId(socket)]) {
var index = socketRooms[sails.sockets.getId(socket)].findIndex(x => x.room == room);
if (index > -1) { //console.log('unsubscribeFromRoom (' + room + ', ' + socket.id + ')---->\n' + JSON.stringify(sockets) + '\n' + JSON.stringify(rooms));
// Update room counters
if (socketRooms[sails.sockets.getId(socket)][index].ui == 'PDB')
roomPeers[room].pdb_count--;
if (socketRooms[sails.sockets.getId(socket)][index].ui == 'PCB')
roomPeers[room].pcb_count--;
var pcb_count = roomPeers[room].pcb_count, sails.log.debug('"websocketUnsubscribe": room ' + room + ', socket ' + socket.id);
pdb_count = roomPeers[room].pdb_count;
if (pcb_count == 0 && pdb_count == 0) var roomType = room.search("student") < 0 ? 'sup_room' : 'stu_room';
delete roomPeers[room];
// Remove socket info sails.sockets.leave(socket, room, function () {
socketRooms[sails.sockets.getId(socket)].splice(index, 1); sails.io.sockets.in(room).clients(function(error, ids) {
if (error) return;
// broadcast data // Delete and notify to old room
sails.hooks.events.broadcastEvent( if (sockets[socket.id]) {
room, var old_room = sockets[socket.id][roomType];
sails.hooks.events.roomSubscribersChange({ delete sockets[socket.id];
'room': room, sails.hooks.rooms.notifyRoom(old_room);
'pdb_count': pdb_count,
'pcb_count': pcb_count
})
);
}
} }
// Remove from room's sockets list
if (rooms[room]) {
var pos = rooms[room].indexOf(socket.id);
if (pos>=0)
rooms[room].splice(pos, 1);
sails.hooks.rooms.notifyRoom(room);
} }
}); });
}); });
}, },
/** /**************************************************************************
* Student related rooms * Student related rooms
* @param {ID} studentId Student's ID used for creating a room. * @param {ID} studentId Student's ID used for creating a room.
* @return {RoomID} RoomID generated * @return {RoomID} RoomID generated
...@@ -154,7 +161,7 @@ module.exports = function roomsHook (sails) { ...@@ -154,7 +161,7 @@ module.exports = function roomsHook (sails) {
return 'studentRoom' + studentId; return 'studentRoom' + studentId;
}, },
/** /**************************************************************************
* Supervisor related rooms * Supervisor related rooms
* @param {ID} supervisorId Supervisor's ID used for creating a room. * @param {ID} supervisorId Supervisor's ID used for creating a room.
* @return {RoomID} RoomID generated * @return {RoomID} RoomID generated
...@@ -163,15 +170,18 @@ module.exports = function roomsHook (sails) { ...@@ -163,15 +170,18 @@ module.exports = function roomsHook (sails) {
return 'supervisorRoom' + supervisorId; return 'supervisorRoom' + supervisorId;
}, },
/** /**************************************************************************
* Disconnect * Disconnect
* Call from config/sockets.js after a socket disconnects * Call from config/sockets.js after a socket disconnects
*/ */
disconnect: function(socket) { disconnect: function(socket) {
var rooms = socketRooms[sails.sockets.getId(socket)]; //console.log('disconnect (' + socket.id + ')---->\n' + JSON.stringify(sockets) + '\n' + JSON.stringify(rooms));
if(!rooms) return; if (sockets[socket.id]) {
for (var i = 0; i < rooms.length; i++) if (sockets[socket.id].stu_room)
sails.hooks.rooms.unsubscribeFromRoom(rooms[i].room, socket); sails.hooks.rooms.unsubscribeFromRoom(sockets[socket.id].stu_room, socket);
if (sockets[socket.id].sup_room)
sails.hooks.rooms.unsubscribeFromRoom(sockets[socket.id].sup_room, socket);
}
} }
}; };
......
...@@ -35,6 +35,7 @@ module.exports.sockets = { ...@@ -35,6 +35,7 @@ module.exports.sockets = {
* * * *
***************************************************************************/ ***************************************************************************/
afterDisconnect: function (session, socket, cb) { afterDisconnect: function (session, socket, cb) {
sails.log.debug("Disconnect socket message received with ID: " + socket.id);
sails.hooks.rooms.disconnect(socket); sails.hooks.rooms.disconnect(socket);
cb(); cb();
}, },
......
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 sign in to comment