Socket.io: socket.rooms adalah objek yang tidak berguna

Dibuat pada 8 Mar 2017  ·  8Komentar  ·  Sumber: socketio/socket.io

Ini mengenai objek socket.rooms , didokumentasikan sebagai:

Sebuah hash string yang mengidentifikasi ruangan tempat klien ini berada, diindeks menurut nama ruangan.

Saya tidak tahu apa artinya, tetapi contohnya jelas:

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

Ketika saya menjalankan console.log(socket.rooms); , saya _ingin_ array cantik itu (jadi saya bisa memotongdan dapatkan kamar saja), tetapi saya mendapatkan kembali objek jelek ini:

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

... yang kemudian harus saya ubah menjadi array dengan .keys() dan kemudian memilih socket.id dengan tangan (karena mungkin bukan yang pertama).

Apakah ini bug? Saya menggunakan 1.7.3.

Komentar yang paling membantu

Yah ini tampaknya tidak perlu rumit. Saya benar-benar berjuang untuk memahami mengapa id soket pengguna merupakan "ruang"?, atau mengapa pasangan kunci:nilai diperlukan. Itu hanya perlu daftar - kamar apa pun yang ada, Anda berada, selesai.

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

Dan seperti di atas, io.rooms untuk mendapatkan semuanya, baik, juga sebagai array string, atau dalam hal ini sebagai objek dengan nama ruangan sebagai kunci dan array id soket sebagai nilainya.

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

Semua 8 komentar

Yah, sepertinya dokumentasinya tidak up-to-date di sini, rooms sebenarnya adalah array sampai v1.4 menurut saya.

Catatan: Saya kira kita bisa menggunakan boolean sebagai nilai.

Saya kira ini adalah permintaan fitur. Jadikan socket.io hebat lagi: kembalikan arraynya!

Tujuan saya di sini adalah untuk mendapatkan array kamar tempat klien berada. Dengan array, saya menganggap socket.id akan menjadi yang pertama:

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

Menggunakan implementasi saat ini:

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

Jika socket.id tidak disertakan, itu juga tidak masalah. Saya hanya tidak ingin harus menemukannya dan mengambilnya.

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

Dengan boolean, saya dapat memfilter nilai sebenarnya, seperti ini (kan?):

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

Yang sama lambatnya dengan iterasi indexOf() .

Ini _akan_ membantu untuk menyertakan ruang di mana klien tidak berada (seperti menunjukkan ruang obrolan yang dapat diikuti klien). Saya hanya berpikir bahwa informasi akan lebih baik di tempat lain, seperti contoh Server :

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

Adakah orang lain yang punya pendapat tentang ini?

Yah ini tampaknya tidak perlu rumit. Saya benar-benar berjuang untuk memahami mengapa id soket pengguna merupakan "ruang"?, atau mengapa pasangan kunci:nilai diperlukan. Itu hanya perlu daftar - kamar apa pun yang ada, Anda berada, selesai.

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

Dan seperti di atas, io.rooms untuk mendapatkan semuanya, baik, juga sebagai array string, atau dalam hal ini sebagai objek dengan nama ruangan sebagai kunci dan array id soket sebagai nilainya.

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

Saya pikir alasan utamanya adalah kinerja pencarian.
Misalnya, ketika pengguna bergabung dengan 100 ruang, akan lebih cepat menggunakan pencarian objek untuk mengetahui apakah ia bergabung dengan ruang daripada mengulangi nilai array.

Lihat jawaban saya di stackoverflow

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

Untuk memeriksa apakah pengguna telah bergabung dengan ruang cukup sederhana seperti ini:
if(socket.rooms[roomID]) return true;

Jika itu tipe array maka kita perlu menggunakan indexOf atau mengulangi setiap array:
if(socket.rooms.indexOf(roomID) != -1) return true;

Tapi saya setuju sepenuhnya jika nilai kunci diubah menjadi boolean:
{ room1: true, ... , room100: true }

Ini dapat membantu menghemat penggunaan memori

Saya tidak keberatan mengubah socket.rooms sehingga nilainya boolean. Apakah tidak apa-apa untuk mengerjakan ini? Saya tidak yakin apa proses kontribusinya karena saya tidak melihat file CONTRIBUTING.md.

Bukankah Set lebih masuk akal?

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

Strukturnya hanya Set(4) {"<socket ID>", "room1", "room2", "room3"} misalnya

Saya setuju selama kompleksitas waktu yang ditetapkan adalah konstan. Saya percaya pada javascript itu.

Di Socket.IO v3, Socket#rooms sekarang akan menjadi Set, dan menggunakan nilai yang disediakan oleh adaptor yang mendasarinya, lihat di sini .

Apakah halaman ini membantu?
0 / 5 - 0 peringkat