Procedimiento completo websockets
Suscribirse a un usuario
Al abrir cualquier ficha del estudiante se suscribe a él (Angular - student/controllers/student.js):
// Subscribe to student's socket room
console.log("connecting to socket");
io.socket.post('/stu/subscribe', {
action: 'subscribe',
attributes:{
id_stu: $scope.studentUser.id
},
token: $window.sessionStorage.token
},
function(res) {
console.log("Connected to student: " + res.msg);
});
La petición se recibe en el servidor (Sails - StudentController.js):
// Subscribe to websockets events
//
subscribe: function(req, res) {
var action = req.param('action');
var attributes = req.param('attributes');
var roomName = 'studentRoom' + attributes.id_stu;
sails.log.debug("Inside /stu/subscribe. Action: " + action);
if (req.isSocket) {
sails.log.debug("Inside /stu/subscribe - isSocket");
sails.sockets.join(req.socket, roomName);
res.json({
msg: "Subscribed to student " + roomName
});
}
},
Cancelar suscripción a todos los usuarios
Al abrir el listado de alumnos se cancela la suscripción a todos los alumnos (Angular - supervisor/controllers/students.js):
// Unsubscribe to student's socket room
io.socket.post('/stu/unsubscribe', {
action: 'unsubscribe'
},
function(res) {
console.log("Disconnected socket: " + res.msg);
});
La petición se recibe en el servidor (Sails - StudentController.js):
// Unsubscribe to websockets events
//
unsubscribe: function(req, res) {
var action = req.param('action');
//var attributes = req.param('attributes');
sails.log.debug("Inside /stu/unsubscribe. Action: " + action);
if (req.isSocket) {
sails.log.debug("Inside /stu/unsubscribe - isSocket");
var rooms = sails.sockets.socketRooms(req.socket);
console.log("Subscribed rooms in socket: " + JSON.stringify(rooms));
// Leave all rooms
for(var i=0; i<rooms.length; i++){
sails.sockets.leave(req.socket, rooms[i]);
sails.log.debug("Unsusbscribe from room " + room[i]);
}
res.json({
msg: "Unsubscribed from all rooms"
});
}
},
Enviar acción sobre el vocabulario a todos los suscritos a un usuario.
Lanzar un mensaje de broadcast a todos los suscritos. Un ejemplo de eliminar un picto (Angular - student/controllers/collections.js):
// websocket emit vocabulary delete action
io.socket.post('/stu/vocabulary', {
action: 'delete',
attributes: {
id_stu: $scope.studentUser.id,
picto: data
}
},
function(res) {
console.log("Vocabulary emited: " + JSON.stringify(res.msg));
});
De forma similar al ejemplo anterior con acción delete
se hacen las acciones add
y update
sobre el vocabulario (/stu/vocabulary) o sobre los ensayos (/stu/action) y la configuración del estudiante (/stu/config).
Más info: Acciones en sesiones de trabajo
La petición se recibe en el servidor que genera un mensaje de broadcast a todos los suscritos (Sails - StudentController.js):
// Logs a vocabulary action and broadcast to anyone subscribed to this student
vocabulary: function(req, res) {
var action = req.param('action');
var attributes = req.param('attributes');
var roomName = 'studentRoom' + attributes.id_stu;
sails.log.debug("Inside vocabulary");
if (req.isSocket) {
sails.log.debug("Inside vocabulary - isSocket");
// Send to all sockets subscribed to this room except the own socket that sends the message
// Parameters: room, action, data to send, socket to avoid sending (the socket that send this)
sails.sockets.broadcast(roomName, 'vocabulary', { "action": action, "attributes": attributes }, req.socket);
res.json({
msg: "Vocabulary "+ action +" action from student " + attributes.id_stu
});
}
},
Gestionar las acciones lanzadas
Escucha de dichos mensajes desde el cliente (Angular - student/controllers/collections.js):
// websockets events handling
io.socket.on('vocabulary', function(data) {
console.log('Vocabulary '+ data.action +' event received with the following data:');
console.log(JSON.stringify(data.attributes));
//$scope.pictos.push(data.attributes.picto.picto);
switch(data.action){
case 'add':
console.log("add action!!!!!!!!!!!!!");
$scope.reload_pictos();
break;
case 'update':
console.log("update action!!!!!!!!!!!!!");
$scope.reload_pictos();
break;
case 'delete':
console.log("delete action!!!!!!!!!!!!");
$scope.reload_pictos();
break;
}
// Socket.io does not live inside the angular lifecycle, and thus Angular
// doesn't know new data has come in. Inside the socket.io callback,
// as the last action, added $scope.apply() that lets angular know
// what data has updated, and refresh what needs to be refreshed.
$scope.$apply();
});