solving problems with rooms handling

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