【问题标题】:how to list rooms on socket.io nodejs server如何在socket.io nodejs服务器上列出房间
【发布时间】:2011-10-01 16:04:23
【问题描述】:

在问题how to create socket.io multicast groups 取得进展后,我发现制作房间是满足我需要的好方法。

但是,如果没有额外的数据结构,了解所有房间会很棒。

是否可以从服务器套接字获取服务器上所有房间的列表?

【问题讨论】:

  • 哎呀完全错过了这个答案,但希望我下面的回答可以帮助你。

标签: node.js multicast socket.io


【解决方案1】:

简短的回答:

io.sockets.adapter.rooms

我分析了io

我得到以下输出:

{ server: 
   { stack: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     connections: 3,
     allowHalfOpen: true,
     watcher: { host: [Circular], callback: [Function] },
     _events: 
      { request: [Function],
        connection: [Function: connectionListener],
        listening: [Object],
        upgrade: [Object] },
     httpAllowHalfOpen: false,
     cache: {},
     settings: { home: '/', env: 'development', hints: true },
     redirects: {},
     isCallbacks: {},
     _locals: { settings: [Object], app: [Circular] },
     dynamicViewHelpers: {},
     errorHandlers: [],
     route: '/',
     routes: 
      { app: [Circular],
        routes: [Object],
        params: {},
        _params: [],
        middleware: [Function] },
     router: [Getter],
     __usedRouter: true,
     type: 'tcp4',
     fd: 7 },
  namespaces: 
   { '': 
      { manager: [Circular],
        name: '',
        sockets: [Object],
        auth: false,
        flags: [Object],
        _events: [Object] } },
  sockets: 
   { manager: [Circular],
     name: '',
     sockets: { '210837319844898486': [Object] },
     auth: false,
     flags: { endpoint: '', exceptions: [] },
     _events: { connection: [Function] } },
  settings: 
   { origins: '*:*',
     log: true,
     store: 
      { options: undefined,
        clients: [Object],
        manager: [Circular] },
     logger: { colors: true, level: 1 },
     heartbeats: true,
     resource: '/socket.io',
     transports: 
      [ 'websocket',
        'htmlfile',
        'xhr-polling',
        'jsonp-polling' ],
     authorization: [Function],
     'log level': 1,
     'close timeout': 25,
     'heartbeat timeout': 15,
     'heartbeat interval': 20,
     'polling duration': 20,
     'flash policy server': true,
     'flash policy port': 843,
     'destroy upgrade': true,
     'browser client': true,
     'browser client minification': false,
     'browser client etag': false,
     'browser client handler': false,
     'client store expiration': 15 },
  handshaken: 
   { '210837319844898486': 
      { headers: [Object],
        address: [Object],
        time: 'Mon Jul 18 2011 00:53:27 GMT+0200 (CEST)',
        xdomain: false,
        secure: undefined,
        PHPSESSID: '7qo6cht3q0rskhfes4eesb2d05' } },
  connected: { '210837319844898486': true },
  open: { '210837319844898486': true },
  closed: {},
  closedA: [],
  rooms: 
   { '': [ '210837319844898486' ],
     '/public-alfred': [ '210837319844898486' ] },
  roomClients: { '210837319844898486': [ '': true, '/public-alfred': true ] },
  oldListeners: [ [Function] ],
  _events: 
   { 'set:origins': [Function],
     'set:flash policy port': [Function],
     'set:transports': [Function] } }

从单个客户io.sockets.adapter.rooms 加入房间“public-alfred”后,包含:

 { '': [ '210837319844898486' ],
         '/public-alfred': [ '210837319844898486' ] }

【讨论】:

  • 或者更简单,io.rooms 就像io.sockets.manager 一样是循环引用。他们会给你同样的东西,只是 io.rooms 不那么冗长。
  • 我认为这不适用于 socket.io 1.0 版。可能是? io.nsps['/'].adapter.rooms
  • Alfred,我编辑了两个 API 版本的答案,有潜在的读者仍然像我一样使用 9.x :)
  • simple socket.rooms 现在可以解决问题.. 必须热爱进步 ;)
  • @Alfred,我使用的是 1.4.x 版本。如何获取io.sockets.adapters.rooms 中每个房间的房间名称?当我创建一个房间并加入时,我给它分配了一个像 socket.join('someRoom') 这样的名字,但是当我使用 io.sockets.adapters.rooms 时,我得到一个像 /#4Ps4Ql-bx2R3qFH6AAAC 这样的引用。如何获取对应的名称?
【解决方案2】:

在新版本的 socket.io (1.x) 中,io.sockets.manager.rooms 会导致错误。你应该改用io.sockets.adapter.rooms

【讨论】:

  • @slier:这是正确的,只有第一个对象是默认房间 - 它看起来像一个随机字符串 -
【解决方案3】:

正如大家所说,在新版本的 socket.io (1.x) 中,可以在以下位置找到房间:

    io.sockets.adapter.rooms

这将返回如下内容:

{ 
    'qNADgg3CCxESDLm5AAAA': [ 'qNADgg3CCxESDLm5AAAA': true ],
    'myRoom': [ 'qNADgg3CCxESDLm5AAAA': true,
                '0rCX3v4pufWvQ6uwAAAB': true,
                'iH0wJHGh-qKPRd2RAAAC': true ],  
    '0rCX3v4pufWvQ6uwAAAB': [ '0rCX3v4pufWvQ6uwAAAB': true ],  
    'iH0wJHGh-qKPRd2RAAAC': [ 'iH0wJHGh-qKPRd2RAAAC': true ] 
}

我想要获得的唯一房间是“myRoom”,所以我为此编写了以下函数:

function findRooms() {
    var availableRooms = [];
    var rooms = io.sockets.adapter.rooms;
    if (rooms) {
        for (var room in rooms) {
            if (!rooms[room].hasOwnProperty(room)) {
                availableRooms.push(room);
            }
        }
    }
    return availableRooms;
}

这让我有点困惑,希望这会有所帮助!

【讨论】:

  • 您的 findRooms() 函数不断将所有房间返回给我,因为该数组中的所有项目都具有属性 room。我在socket.io v1.4.5
【解决方案4】:

在socketIO 2.2.0版本中,

  • io.sockets.manager 不存在了

您可以使用以下 3 获取特定房间中的所有插座。

socket.adapter.rooms;
io.sockets.adapter.rooms
io.sockets.adapter.sids

如果您使用命名空间,您应该使用socket.adapter.rooms 来获取房间列表。

{ '/userSocket#oXorUiql1GF68dbTAAAB':
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
     },
  roomOneName:
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
     },
  roomTwoName:
   Room {
     sockets: { '/userSocket#oXorUiql1GF68dbTAAAB': true },
     length: 1 
   } 
}

【讨论】:

    【解决方案5】:

    如果你正在使用

    socket.io 2.1.0

    偶然发现了这个。

    在 2.1.0 中,服务器中的所有房间都位于变量 io.sockets.adapter.rooms

    //Use Example//
    
    sockets.on('getRooms', function() {
        sockets.emit('rooms', io.sockets.adapter.rooms);
    });
    

    你会得到以下结果。

    { xqfGuWYkKzT9hGgGAAAB: 房间 { 插座: { xqfGuWYkKzT9hGgGAAAB: true },长度:1 },'0Ak9nTjme7bLsD8NAAAC':房间 { 套接字:{ '0Ak9nTjme7bLsD8NAAAC':真 },长度:1 } }

    【讨论】:

      【解决方案6】:

      如果io.sockets.adapterundefined..

      我正在使用 socket.io 1.7.1(服务器)

      socket.io 的那个版本上,io.of("......").sockets.adapter 似乎是undefined。所以我改用io.adapter.rooms,它可以工作。

      【讨论】:

      • io.sockets.adapter.rooms 在 Socket.IO 1.7.3 中工作。
      【解决方案7】:
      Object.keys(io.sockets.adapter.rooms)
      

      使用它来获取所有房间。

      【讨论】:

        【解决方案8】:

        我能够在打开的连接上使用 socket._events 找到它们。

        io.sockets.on('connection', function(socket){
          socket.on('ping', function(data){
            console.log(socket._events);
          });
        });
        

        输出:

        {
          ping: [Function],
          disconnect: [Function]
        }
        

        【讨论】:

        • 我相信 OP 询问了如何找到房间。这将是事件。在某些情况下仍然有帮助,但与这个问题无关。
        【解决方案9】:

        在 Socketio 2.0 中

        让房间使用

        Object.keys(socket.adapter.rooms);
        

        获取房间名称

        Object.keys(socket.adapter.rooms)[1];
        

        【讨论】:

          【解决方案10】:

          过滤掉“真实”房间可以这样完成:

          var realRooms = Object.keys(io.sockets.adapter.rooms).reduce((filtered, key) => {
              if(!io.sockets.adapter.rooms[key].sockets.hasOwnProperty(key)) filtered.push(key);
              return filtered;
          }, []);
          

          【讨论】:

            【解决方案11】:

            根据Socket.io-v3.x 的文档,要创建所有当前房间,您只需执行socket.rooms

            io.on('connection', socket => {
            
              console.log(socket.rooms);
              socket.on('disconnect', () => {
                // socket.rooms.size === 0
              });
            });
            

            它会像这样返回

            Set(2) {
              '_y_xQeeF6PpFiPQqAAFC',
              '6113cb71359644408895afcf6112df3c76981e3f88bc5c08'
            } 
            

            【讨论】:

              【解决方案12】:

              我没有足够的声誉来发表我对原始问题的评论,但此外,如果你想列出命名空间中的所有房间,它应该这样编码:

              var nsp = io.of('/my-nsp');
              
              var rooms = nsp.adapter.rooms;
              

              如果客户通过以下方式加入房间,这将有所帮助:

              socket.join('my-room');
              

              console.log(rooms); 时应该可以看到你的房间名称

              我只是想回答上面未答复的评论,因为我在看到不匹配的房间名称后遇到了同样的问题。

              【讨论】:

              • 对我来说:io.socket.of('').adapter.rooms[room]
              【解决方案13】:
              function ActiveRooms(){
                      var activeRooms = [];
                      Object.keys(io.sockets.adapter.rooms).forEach(room=>{
                          var isRoom = true;
                          Object.keys(io.sockets.adapter.sids).forEach(id=>{
                              isRoom = (id === room)? false: isRoom;
                          });
                          if(isRoom)activeRooms.push(room);
                      });
                      return activeRooms;}
              

              【讨论】:

              • 我知道这是一篇旧帖子,但这就是我所做的。我注意到每个插座的房间里都有 ID。
              猜你喜欢
              • 2019-05-13
              • 1970-01-01
              • 2018-05-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-03-24
              • 1970-01-01
              相关资源
              最近更新 更多