Socket.io: socket.rooms es un objeto inútil

Creado en 8 mar. 2017  ·  8Comentarios  ·  Fuente: socketio/socket.io

Esto se refiere al objeto socket.rooms , documentado como:

Un hash de cadenas que identifican las habitaciones en las que se encuentra este cliente, indexadas por nombre de habitación.

No sé qué significa eso, pero el ejemplo es claro:

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
  });
});

Cuando ejecuto console.log(socket.rooms); , _quiero_ esa bonita matriz (para poder cortary obtengo solo las habitaciones), pero recupero este objeto feo:

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

... que luego tengo que convertir en una matriz con .keys() y luego seleccionar el socket.id a mano (ya que podría no ser el primero).

¿Es esto un error? Estoy usando 1.7.3.

Comentario más útil

Sí, esto parece innecesariamente complicado. Realmente estoy luchando por entender por qué la identificación de socket del usuario constituye una "habitación", o por qué se necesitan pares clave: valor . Solo necesita ser una lista: cualquier habitación que esté presente, en la que se encuentre, listo.

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

Y como arriba, io.rooms para obtenerlos todos, también como una matriz de cadenas, o en este caso como un objeto con nombres de habitaciones como claves y una matriz de identificadores de socket como su valor.

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

Todos 8 comentarios

Bueno, parece que la documentación no está actualizada aquí, creo que rooms era en realidad una matriz hasta la v1.4.

Nota: Supongo que podríamos usar un booleano como valor.

Supongo que esta es una solicitud de función entonces. Haz que socket.io sea genial de nuevo: ¡recupera las matrices!

Mi objetivo aquí es obtener una variedad de habitaciones en las que se encuentra el cliente. Con una matriz, supongo que socket.id sería el primero:

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

Usando la implementación actual:

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

Si los socket.id no estuvieran incluidos, también estaría bien. Simplemente no quiero tener que buscarlo y elegirlo.

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

Con booleanos, podría filtrar los valores verdaderos, así (¿verdad?):

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

Lo cual es tan lento como iterar con indexOf() .

_Sería_ útil incluir salas en las que el cliente no está (como para mostrar las salas de chat a las que puede unirse). Creo que la información sería mejor en otro lugar, como la instancia Server :

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

¿Alguien más tiene una opinión sobre esto?

Sí, esto parece innecesariamente complicado. Realmente estoy luchando por entender por qué la identificación de socket del usuario constituye una "habitación", o por qué se necesitan pares clave: valor . Solo necesita ser una lista: cualquier habitación que esté presente, en la que se encuentre, listo.

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

Y como arriba, io.rooms para obtenerlos todos, también como una matriz de cadenas, o en este caso como un objeto con nombres de habitaciones como claves y una matriz de identificadores de socket como su valor.

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

Creo que la razón principal es el rendimiento de la búsqueda.
Por ejemplo, cuando un usuario se unió a una sala de 100, sería más rápido usar la búsqueda de objetos para averiguar si se unió a una sala en lugar de iterar el valor de la matriz.

Consulte mi respuesta en stackoverflow

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

Para comprobar si el usuario se ha unido a una sala, simplemente haga lo siguiente:
if(socket.rooms[roomID]) return true;

Si es un tipo de matriz, entonces necesitamos usar indexOf o iterar cada matriz:
if(socket.rooms.indexOf(roomID) != -1) return true;

Pero estoy totalmente de acuerdo si el valor de la clave se cambia a un booleano:
{ room1: true, ... , room100: true }

Puede ayudar a ahorrar algo de uso de memoria

No me importaría cambiar socket.rooms para que los valores sean booleanos. ¿Está bien trabajar en esto? No estoy seguro de cuál es el proceso de contribución ya que no vi un archivo CONTRIBUTING.md.

¿No tendría más sentido un Set ?

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

La estructura sería simplemente Set(4) {"<socket ID>", "room1", "room2", "room3"} por ejemplo

Estoy de acuerdo siempre que la complejidad temporal del conjunto sea constante. Creo en javascript que es.

En Socket.IO v3, Socket#rooms ahora será un conjunto y utilizará el valor proporcionado por el adaptador subyacente, consulte aquí .

¿Fue útil esta página
0 / 5 - 0 calificaciones