Socket.io: socket.rooms é um objeto inútil

Criado em 8 mar. 2017  ·  8Comentários  ·  Fonte: socketio/socket.io

Isso se refere ao objeto socket.rooms , documentado como:

Um hash de strings que identifica os quartos em que este cliente está, indexado pelo nome do quarto.

Não sei o que isso significa, mas o exemplo é 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
  });
});

Quando eu executo console.log(socket.rooms); , eu _quero_ aquele lindo array (para que eu possa cortare recebo apenas os quartos), mas eu recebo este objeto feio de volta:

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

... que eu então tenho que transformar em um array com .keys() e então pegar socket.id manualmente (já que pode não ser o primeiro).

Isso é um inseto? Estou usando o 1.7.3.

Comentários muito úteis

Sim, isso parece desnecessariamente complicado. Estou realmente lutando para entender por que o ID de soquete do usuário constitui uma "sala" ?, ou por que pares chave: valor são necessários. Só precisa ser uma lista - quaisquer que sejam as salas presentes, você está pronto.

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

E como acima, io.rooms para obter todos eles, também como um array de string ou, neste caso, como um objeto com nomes de quartos como chaves e um array de ids de soquete como seu valor.

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

Todos 8 comentários

Bem, parece que a documentação não está atualizada aqui, o rooms era na verdade um array até a v1.4, eu acho.

Nota: acho que poderíamos usar um booleano como valor.

Eu acho que este é um pedido de recurso então. Torne o socket.io ótimo novamente: traga de volta os arrays!

Meu objetivo aqui é obter uma matriz de quartos em que o cliente está. Com uma matriz, suponho que socket.id seria o primeiro:

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

Usando a implementação atual:

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

Se os socket.id não estivessem incluídos, também estaria tudo bem. Só não quero ter que encontrar e escolher.

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

Com os booleanos, seria capaz de filtrar os valores verdadeiros, assim (certo?):

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

O que é tão lento quanto iterar com indexOf() .

_Seria_ útil incluir salas nas quais o cliente não esteja (como para mostrar salas de chat nas quais ele pode entrar). Só acho que a informação seria melhor em outro lugar, como a instância Server :

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

Alguém mais tem uma opinião sobre isso?

Sim, isso parece desnecessariamente complicado. Estou realmente lutando para entender por que o ID de soquete do usuário constitui uma "sala" ?, ou por que pares chave: valor são necessários. Só precisa ser uma lista - quaisquer que sejam as salas presentes, você está pronto.

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

E como acima, io.rooms para obter todos eles, também como um array de string ou, neste caso, como um objeto com nomes de quartos como chaves e um array de ids de soquete como seu valor.

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

Acho que o principal motivo é o desempenho da pesquisa.
Por exemplo, quando um usuário ingressou em 100 salas, seria mais rápido usar a pesquisa de objeto para descobrir se ele ingressou em uma sala em vez de iterar o valor do array.

Consulte minha resposta sobre stackoverflow

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

Para verificar se o usuário entrou em uma sala, basta fazer isso:
if(socket.rooms[roomID]) return true;

Se for tipo de array, então precisamos usar indexOf ou iterar cada array:
if(socket.rooms.indexOf(roomID) != -1) return true;

Mas eu concordo totalmente se o valor da chave for alterado para um booleano:
{ room1: true, ... , room100: true }

Pode ajudar a economizar algum uso de memória

Eu não me importaria de mudar socket.rooms para que os valores sejam booleanos. Posso trabalhar nisso? Não tenho certeza de qual é o processo de contribuição, pois não vi um arquivo CONTRIBUTING.md.

Set faria mais sentido?

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

A estrutura seria simplesmente Set(4) {"<socket ID>", "room1", "room2", "room3"} por exemplo

Eu concordo, desde que a complexidade do tempo do set seja constante. Eu acredito em javascript.

No Socket.IO v3, Socket#rooms agora será um Set e usará o valor fornecido pelo adaptador subjacente, veja aqui .

Esta página foi útil?
0 / 5 - 0 avaliações