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 cortar
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.
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 .
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'] }