当前位置:  开发笔记 > 编程语言 > 正文

单行检查套接字是否在给定的房间内?

如何解决《单行检查套接字是否在给定的房间内?》经验,为你挑选了2个好方法。

我正在使用带有socket.io的Node.js进行多人纸牌游戏,还有玩家可以加入的游戏室.

为了加入一个房间,我只需使用:

io.sockets.on('connection', function (socket) {
    socket.on('joinRoom', function (gid) {
        //gid is game ID - create room name based on this and join the room
        var room = 'game'+gid;
        socket.join(room);
    });
});

我的问题是,检查套接字是否连接到某个房间的最快方法是什么?我知道我可以在一个数组中获取该房间中的所有套接字,然后检查目标套接字是否在数组中,但我猜测应该有更基本的语法.我正在寻找(伪代码)将是

if(socket with ID "z8b7dbf98i" is in room "game10")
    //do something

小智.. 13

对于文档,socket.io似乎没有任何简单的方法来做到这一点.您确实需要检查客户端是否在房间阵列中,或者相反:如果房间在客户端阵列中.

这可以通过oneliner使用indexOf:

if(socket.rooms.indexOf(room) >= 0)

或者相反的搜索:

if(io.sockets.manager.rooms['/' + room].indexOf(socket.id) >= 0)


Amol M Kulka.. 7

你可以这样检查一下
io.sockets.adapter.rooms['roomId']

这会返回一个带有sId的对象,例如
{"1sEAEIZeuMgdhF35AAAA":true}


特定于版本的更新:

1.4+:

io.sockets.adapter.rooms['roomId']

1.3.x的:

io.sockets.adapter.rooms['roomId']; 

1.0.x到1.2.x:

io.adapter.rooms['roomId'];


更新:
但是,只有当服务器体系结构具有单节点服务器/单节点进程时,才可以检查套接字ID是否在给定空间中,如上所述使用单行.

如果您使用的是多节点服务器,即具有负载平衡的单独节点进程.

这里要注意的是,套接字仅在它们首次连接的进程上注册.因此,您需要使用socket.io-redis将所有节点连接在一起以同步事件,并且每次客户端连接/断开连接时,您可以执行的维护多节点上的套接字ID列表的事件是广播事件,以便每个节点更新并维护所有客户端/套接字ID的实时列表.

背景/详细信息:
redis适配器扩展了基本适配器,但它只覆盖/添加以下属性:
clients broadcast add del delAll

使用以下代码:

io.sockets.adapter.rooms["roomId"]; //Any of the above examples specific to versions mentioned above

你在socket.io-redis适配器上查询房间属性.这没有被redis适配器覆盖,所以你实际上是在查询基本适配器,它只知道当前进程中的房间/客户端.

为什么redis适配器没有覆盖房间属性?可能是因为它必须查询redis数据库实例以构造一个对象,该对象包含该属性的每次访问的所有房间和连接.不是个好主意?

因此,在撰写本文时,您必须使用以下方法将该功能添加到适配器本身:

/**
   * One-Line code/property to check if the socket id is in given room.
   *
   * @param {String} room id
   * @param {Function} callback (optional)
   * @api public
   */

  Redis.prototype.isSidExistsInRoom = function(room, fn){ ... }

你将在哪里点击redis数据库实例.

这应该是所有其他适配器实现的基本适配器接口的一部分.当他们扩展服务器时,每天都会遇到一个普遍的问题;)

PS只是提示另一种方法是在socket.io-redis 3.1.0中使用customRequest/customHook方法.


使用ver 5.2.0进行更新:(相关的多节点服务器)
现在,从5.2.0开始,redis适配器为您提供跨进程/节点的空间
源:RedisAdapter#clients(rooms:Array,fn:Function)

返回跨所有节点连接到房间的客户端ID列表.请参阅命名空间#客户端(fn:Function)

io.of('/').adapter.clients((err, clients) => {
  console.log(clients); // an array containing all connected socket ids
});

io.of('/').adapter.clients(['room1', 'room2'], (err, clients) => {
  console.log(clients); // an array containing socket ids in 'room1' and/or 'room2'
});

// you can also use

io.in('room3').clients((err, clients) => {
  console.log(clients); // an array containing socket ids in 'room3'
});


快乐的编码!



1> 小智..:

对于文档,socket.io似乎没有任何简单的方法来做到这一点.您确实需要检查客户端是否在房间阵列中,或者相反:如果房间在客户端阵列中.

这可以通过oneliner使用indexOf:

if(socket.rooms.indexOf(room) >= 0)

或者相反的搜索:

if(io.sockets.manager.rooms['/' + room].indexOf(socket.id) >= 0)



2> Amol M Kulka..:

你可以这样检查一下
io.sockets.adapter.rooms['roomId']

这会返回一个带有sId的对象,例如
{"1sEAEIZeuMgdhF35AAAA":true}


特定于版本的更新:

1.4+:

io.sockets.adapter.rooms['roomId']

1.3.x的:

io.sockets.adapter.rooms['roomId']; 

1.0.x到1.2.x:

io.adapter.rooms['roomId'];


更新:
但是,只有当服务器体系结构具有单节点服务器/单节点进程时,才可以检查套接字ID是否在给定空间中,如上所述使用单行.

如果您使用的是多节点服务器,即具有负载平衡的单独节点进程.

这里要注意的是,套接字仅在它们首次连接的进程上注册.因此,您需要使用socket.io-redis将所有节点连接在一起以同步事件,并且每次客户端连接/断开连接时,您可以执行的维护多节点上的套接字ID列表的事件是广播事件,以便每个节点更新并维护所有客户端/套接字ID的实时列表.

背景/详细信息:
redis适配器扩展了基本适配器,但它只覆盖/添加以下属性:
clients broadcast add del delAll

使用以下代码:

io.sockets.adapter.rooms["roomId"]; //Any of the above examples specific to versions mentioned above

你在socket.io-redis适配器上查询房间属性.这没有被redis适配器覆盖,所以你实际上是在查询基本适配器,它只知道当前进程中的房间/客户端.

为什么redis适配器没有覆盖房间属性?可能是因为它必须查询redis数据库实例以构造一个对象,该对象包含该属性的每次访问的所有房间和连接.不是个好主意?

因此,在撰写本文时,您必须使用以下方法将该功能添加到适配器本身:

/**
   * One-Line code/property to check if the socket id is in given room.
   *
   * @param {String} room id
   * @param {Function} callback (optional)
   * @api public
   */

  Redis.prototype.isSidExistsInRoom = function(room, fn){ ... }

你将在哪里点击redis数据库实例.

这应该是所有其他适配器实现的基本适配器接口的一部分.当他们扩展服务器时,每天都会遇到一个普遍的问题;)

PS只是提示另一种方法是在socket.io-redis 3.1.0中使用customRequest/customHook方法.


使用ver 5.2.0进行更新:(相关的多节点服务器)
现在,从5.2.0开始,redis适配器为您提供跨进程/节点的空间
源:RedisAdapter#clients(rooms:Array,fn:Function)

返回跨所有节点连接到房间的客户端ID列表.请参阅命名空间#客户端(fn:Function)

io.of('/').adapter.clients((err, clients) => {
  console.log(clients); // an array containing all connected socket ids
});

io.of('/').adapter.clients(['room1', 'room2'], (err, clients) => {
  console.log(clients); // an array containing socket ids in 'room1' and/or 'room2'
});

// you can also use

io.in('room3').clients((err, clients) => {
  console.log(clients); // an array containing socket ids in 'room3'
});


快乐的编码!

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有