Socket.io: socket.rooms ist ein nutzloses Objekt

Erstellt am 8. März 2017  ·  8Kommentare  ·  Quelle: socketio/socket.io

Dies betrifft das Objekt socket.rooms , dokumentiert als:

Ein Hash von Strings, die die Räume identifizieren, in denen sich dieser Client befindet, indiziert nach Raumnamen.

Ich weiß nicht, was das bedeutet, aber das Beispiel ist klar:

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

Wenn ich console.log(socket.rooms); ausführe, _will_ ich dieses hübsche Array (damit ich es abschneiden kannund bekomme nur die Räume), aber ich bekomme dieses hässliche Objekt zurück:

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

... die ich dann mit .keys() in ein Array socket.id von Hand heraussuchen muss (da es vielleicht nicht die erste ist).

Ist das ein Fehler? Ich verwende 1.7.3.

Hilfreichster Kommentar

Ja, das scheint unnötig kompliziert zu sein. Ich habe wirklich Mühe zu verstehen, warum die Socket-ID des Benutzers ein "Raum" ist oder warum Schlüssel:Wert- Paare benötigt werden. Es muss nur eine Liste sein - egal welche Räume vorhanden sind, Sie sind drin, fertig.

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

Und wie oben, io.rooms, um sie alle zu bekommen, entweder auch als String-Array, oder in diesem Fall als Objekt mit Raumnamen als Schlüssel und einem Array von Socket-IDs als Wert.

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

Alle 8 Kommentare

Nun, es scheint, dass die Dokumentation hier nicht auf dem neuesten Stand ist, das rooms war tatsächlich bis v1.4 ein Array, denke ich.

Hinweis: Ich denke, wir könnten einen booleschen Wert als Wert verwenden.

Ich denke, das ist dann eine Feature-Anfrage. Machen Sie socket.io wieder großartig: Bringen Sie die Arrays zurück!

Mein Ziel hier ist es, ein Array von Räumen zu erhalten, in denen sich der Client befindet. Bei einem Array gehe ich davon aus, dass socket.id an erster Stelle steht:

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

Mit der aktuellen Implementierung:

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

Wenn die socket.id nicht enthalten wären, wäre es auch in Ordnung. Ich will es nur nicht suchen und aussuchen müssen.

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

Mit booleschen Werten könnte ich die wahren Werte wie folgt herausfiltern (oder?):

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

Das ist genauso langsam wie das Iterieren mit indexOf() .

Es _wäre_ hilfreich, Räume einzubeziehen, in denen sich der Kunde nicht befindet (z. B. um Chaträume anzuzeigen, denen er beitreten kann). Ich denke nur, dass diese Informationen an anderer Stelle besser wären, wie in der Instanz Server :

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

Hat noch jemand eine Meinung dazu?

Ja, das scheint unnötig kompliziert zu sein. Ich habe wirklich Mühe zu verstehen, warum die Socket-ID des Benutzers ein "Raum" ist oder warum Schlüssel:Wert- Paare benötigt werden. Es muss nur eine Liste sein - egal welche Räume vorhanden sind, Sie sind drin, fertig.

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

Und wie oben, io.rooms, um sie alle zu bekommen, entweder auch als String-Array, oder in diesem Fall als Objekt mit Raumnamen als Schlüssel und einem Array von Socket-IDs als Wert.

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

Ich denke, der Hauptgrund ist die Suchleistung.
Wenn ein Benutzer beispielsweise 100 Räumen beigetreten ist, wäre es schneller, die Objektsuche zu verwenden, um herauszufinden, ob er einem Raum beigetreten ist, anstatt den Array-Wert zu iterieren.

Siehe meine Antwort auf Stackoverflow

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

So überprüfen Sie, ob der Benutzer einem Raum beigetreten ist:
if(socket.rooms[roomID]) return true;

Wenn es sich um einen Array-Typ handelt, müssen wir indexOf verwenden oder jedes Array iterieren:
if(socket.rooms.indexOf(roomID) != -1) return true;

Aber ich stimme voll und ganz zu, wenn der Schlüsselwert in einen booleschen Wert geändert wird:
{ room1: true, ... , room100: true }

Es kann helfen, etwas Speicherverbrauch zu sparen

Ich hätte nichts dagegen, socket.rooms so zu ändern, dass die Werte boolesche Werte sind. Ist es in Ordnung, daran zu arbeiten? Ich bin mir nicht sicher, was der Beitragsprozess ist, da ich keine CONTRIBUTING.md-Datei gesehen habe.

Wäre ein Set nicht sinnvoller?

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

Die Struktur wäre zum Beispiel einfach Set(4) {"<socket ID>", "room1", "room2", "room3"}

Ich stimme zu, solange die Zeitkomplexität des Sets konstant ist. Ich glaube an Javascript ist es.

In Socket.IO v3 ist Socket#rooms jetzt ein Set und verwendet den vom zugrunde liegenden Adapter bereitgestellten Wert, siehe hier .

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen