Socket.io: socket.rooms est un objet inutile

Créé le 8 mars 2017  ·  8Commentaires  ·  Source: socketio/socket.io

Il s'agit de l'objet socket.rooms , documenté comme

Un hachage de chaînes identifiant les salles dans lesquelles se trouve ce client, indexé par nom de salle.

Je ne sais pas ce que cela signifie, mais l'exemple est clair :

io.on('connection', function(socket){
  socket.join('room 237', function(){
    console.log(socket.rooms); // [ <socket.id>, 'room 237' ]
    io.to('room 237', 'a new user has joined the room'); // broadcast to everyone in the room
  });
});

Quand je lance console.log(socket.rooms); , je _veux_ ce joli tableau (pour pouvoir couperet récupérer juste les chambres), mais je récupère ce vilain objet :

io.on('connection', function(socket){
  socket.join('room 237', function(){
    console.log(socket.rooms); // { <socket.id>: '<socket.id>', 'room 237': 'room 237' }
  });
});

... que je dois ensuite transformer en un tableau avec .keys() , puis choisir les socket.id à la main (car ce n'est peut-être pas le premier).

Est-ce un bug ? J'utilise 1.7.3.

Commentaire le plus utile

Yah cela semble inutilement compliqué. J'ai vraiment du mal à comprendre pourquoi l'identifiant de socket de l'utilisateur constitue une "salle" ?, ou pourquoi des paires

['room1', 'room2', 'room3']

Et comme ci-dessus, io.rooms pour les obtenir tous, soit également sous forme de tableau de chaînes, soit dans ce cas sous forme d'objet avec des noms de pièce comme clés et un tableau d'identifiants de socket comme valeur.

{ room1: ['id1', 'id2', 'id3'], room2: ['id4', 'id5', 'id6'] }

Tous les 8 commentaires

Eh bien, il semble que la documentation ne soit pas à jour ici, le rooms était en fait un tableau jusqu'à la v1.4 je pense.

Remarque : Je suppose que nous pourrions utiliser un booléen comme valeur.

Je suppose que c'est une demande de fonctionnalité alors. Rendez socket.io génial à nouveau : ramenez les tableaux !

Mon objectif ici est d'obtenir un tableau de pièces dans lesquelles se trouve le client. Avec un tableau, je suppose que le socket.id serait le premier :

var rooms = socket.rooms.slice(1);

Utilisation de l'implémentation actuelle :

var roomKeys = Object.keys(socket.rooms);
var socketIdIndex = roomKeys.indexOf( socket.id );
var rooms = roomKeys.splice( socketIdIndex, 1 );

Si les socket.id n'étaient pas inclus, ce serait bien aussi. Je ne veux pas avoir à le trouver et à le choisir.

var rooms = Object.keys(socket.rooms);

Avec des booléens, je serais capable de filtrer les vraies valeurs, comme ceci (non?):

var roomKeys = Object.keys(socket.rooms);
var rooms = roomKeys.filter(function(key){ 
  return socket.rooms[key]==true;
});

Ce qui est aussi lent que d'itérer avec indexOf() .

Il _serait_ utile d'inclure des salons dans lesquels le client n'est pas (par exemple, pour montrer les salons de discussion auxquels il peut se joindre). Je pense juste que l'information serait meilleure ailleurs, comme l'instance Server :

var allRooms = io.rooms;
var myRooms = socket.rooms;

Quelqu'un d'autre a un avis à ce sujet ?

Yah cela semble inutilement compliqué. J'ai vraiment du mal à comprendre pourquoi l'identifiant de socket de l'utilisateur constitue une "salle" ?, ou pourquoi des paires

['room1', 'room2', 'room3']

Et comme ci-dessus, io.rooms pour les obtenir tous, soit également sous forme de tableau de chaînes, soit dans ce cas sous forme d'objet avec des noms de pièce comme clés et un tableau d'identifiants de socket comme valeur.

{ room1: ['id1', 'id2', 'id3'], room2: ['id4', 'id5', 'id6'] }

Je pense que la raison principale est la performance de recherche.
Pour l'exemple, lorsqu'un utilisateur a rejoint une salle 100, il serait plus rapide d'utiliser la recherche d'objets pour savoir s'il a rejoint une salle plutôt que d'itérer la valeur du tableau.

Référez-vous à ma réponse sur stackoverflow

{
    "room1":"room1",
    "room2":"room2",
    ...
    "room100":"room100"
}

Pour vérifier si l'utilisateur a rejoint une salle, c'est simple comme ceci :
if(socket.rooms[roomID]) return true;

S'il s'agit de type tableau, nous devons utiliser indexOf ou itérer chaque tableau :
if(socket.rooms.indexOf(roomID) != -1) return true;

Mais je suis tout à fait d'accord si la valeur de la clé est remplacée par un booléen :
{ room1: true, ... , room100: true }

Cela peut aider à économiser de la mémoire

Cela ne me dérangerait pas de changer socket.rooms pour que les valeurs soient booléennes. Est-ce que c'est bien de travailler là-dessus ? Je ne sais pas quel est le processus de contribution car je n'ai pas vu de fichier CONTRIBUTING.md.

Un Set n'aurait-il pas plus de sens ?

if (socket.rooms.has(roomID)) return true;

La structure serait simplement Set(4) {"<socket ID>", "room1", "room2", "room3"} par exemple

Je suis d'accord tant que la complexité temporelle de l'ensemble est constante. Je crois que c'est en javascript.

Dans Socket.IO v3, Socket#rooms sera désormais un ensemble et utilisera la valeur fournie par l'adaptateur sous-jacent, voir ici .

Cette page vous a été utile?
0 / 5 - 0 notes