socket.io房间还是命名空间?

192

我正在研究实时聊天的nodejs/socket.io,并需要一些实现房间的建议。

使用命名空间还是使用房间特性将聊天者完全隔离开来更好?

房间和命名空间之间的真正技术差别是什么?

是否有任何资源使用差异?

8个回答

252
这是命名空间和房间共同点的介绍(socket.io v0.9.8 - 请注意v1.0进行了完全重写,因此可能有所改变):
- 命名空间(io.of('/nsp'))和房间(socket.join('room'))都是在服务器端创建的。 - 多个命名空间和多个房间共享相同的(WebSocket)连接。 - 服务器只会将消息传输到连接/加入nsp/房间的客户端,即不仅仅是客户端过滤。
它们之间的区别是:
- 命名空间是分离的通信管道,而房间是在命名空间内部的逻辑分组。
  • 客户端使用io.connect(urlAndNsp)连接命名空间(如果服务器上已经存在该命名空间,则客户端将仅添加到该命名空间)
  • 房间只能在服务器端加入(虽然在服务器端创建一个API以使客户端加入是简单的)
  • 命名空间可以受到授权保护
  • 房间不支持授权,但可以在服务器上的易于创建的API中添加自定义授权,以防一定要使用房间
  • 房间是命名空间的一部分(默认为“全局”命名空间)
  • 命名空间始终根源于全局范围

为了不混淆概念和名称(房间或命名空间),我将使用compartment来指代概念,而另外两个名称则用于概念的实现。所以如果您

  • 需要按隔间授权,使用命名空间可能是最简便的方法。
  • 如果您想要分层隔间(最多2层),请使用命名空间/房间组合。
  • 如果您的客户端应用程序由不同的部分组成(它们本身并不关心隔间,但)需要彼此分离,请使用命名空间。

后一种情况的一个例子是一个大型客户端应用程序,其中不同的模块,也许是单独开发的(例如第三方),每个模块都独立地使用socket.io,并在同一个应用程序中使用并共享一个网络连接。

没有实际基准测试,但在我看来,如果您只需要在项目中简单地隔离和分组消息,则两种方法都可以。

不确定是否回答了您的问题,但导致这个答案的研究至少帮助我更清楚地看到了问题。


6
1.0 版本及以上的 socket.io 是否有任何重大的更改? - Xeroxoid
2
最新版本的更改,请阅读http://socket.io/docs/rooms-and-namespaces/,这个答案可以帮助理解房间事物。 https://dev59.com/TmAg5IYBdhLWcg3wBXOs#24224146 - Gonzalo Bahamondez
1
我们可以说命名空间是我的 Web 应用程序中的某个区域,而房间则是该区域内的一组客户端吗? - Onaiggac
你能补充一些关于从房间/命名空间断开连接时的情况吗?当客户端暂时断开连接或失去连接时,它们会发生什么。在这里写道:* 断开连接时,套接字自动离开它们所在的所有频道,并且您不需要进行任何特殊的拆除操作。* “频道”和“区域”是相同的吗? - Wilt

84

这是一个老问题,但在对该主题进行一些研究后,我发现被接受的答案在一个重要点上不够清晰。根据Guillermo Rauch本人的说法(请参见链接):虽然在运行中创建命名空间是理论上可能的,但您主要将它们用作应用程序中预定义的单独部分。另一方面,如果您需要创建临时区段以容纳用户/连接组,则最好使用房间。


6
喜欢它!命名空间 - 预定义连接。房间 - 动态连接。 - Nandakumar

23

这取决于你想做什么。

主要区别在于房间更难实现。 您必须编写一个方法来加入房间,并在每次页面重新加载时执行。

使用命名空间,您只需要在javascript客户端中编写var example = io.connect('http://localhost/example');,客户端会自动添加到命名空间中。

使用示例:

  • 房间:私人聊天。
  • 命名空间:页面聊天。

7

房间和命名空间可以分组单独的套接字进行通讯。

向房间或命名空间广播不会将消息发送给所有人,而是只发送给成员。

命名空间和房间之间的区别如下:

  • 命名空间:在前端管理,意味着用户或攻击者通过前端加入和断开连接,在此处进行管理。
  • 房间:在后端管理,意味着服务器指定加入和离开的房间。

主要区别在于谁管理它们。

为了决定使用哪种方式,您必须决定分割应该在前端还是后端进行管理。


1
您仍然可以通过授权来保护命名空间以防止攻击。 - daniel rubambura
实际上,@danielrubambura没有权限的用户将无法在前端设置它,尽管它可能会被已验证的攻击者创建。假设我创建了一个命名空间,由于某种原因显示为聊天室,是公共的,它可以被命名为@#$! @#$!然后我们将增加许多复杂性,需要对这种名称进行清理和检查。这只是我能想到的一件事情。虽然我提到的场景可能会发生,但我明白使用命名空间不是本质的。 - zardilior
1
如果通过查询字符串传递身份验证令牌,则还存在中间人攻击的可能。提醒一下,您需要使用令牌进行两次往返以避免此问题。 - camwhite

5

命名空间可以包含房间,这有助于组织代码,但是不能在房间内包含命名空间。 因此,命名空间是顶级分段,而房间是较低级别的分段。


4
命名空间允许您创建具有相同名称的对象,但它们将分别存在于不同的命名空间中,也称为作用域。
这与Socket.IO命名空间的思路是一致的。如果您正在构建模块化的Node Web应用程序,则需要对不同模块进行命名空间处理。如果您回顾我们的命名空间代码,您将看到我们能够在不同的命名空间中侦听完全相同的事件。在Socket.IO中,默认连接上的连接事件和/xxx命名空间上的连接事件是不同的。例如,如果您在站点上拥有聊天和评论系统,并希望两者都实时更新,那么您可以为每个系统设置命名空间。这使您能够构建仅在其自己的上下文中运行的整个Socket.IO应用程序。
如果您要构建要打包和安装的内容,这也是正确的做法。您无法知道某个人是否已经在默认命名空间中使用了某些事件,因此您应该创建自己的命名空间并在那里侦听。这使您不会干扰任何使用您的软件包的开发人员。
命名空间允许我们将连接划分为不同的上下文。我们可以将其比作房间,这样我们就可以将连接组合在一起。然后,我们还可以让同一个连接加入其他房间。
命名空间允许您为Socket.IO创建不同的上下文。房间允许您将客户端连接分组在这些上下文中。

1

简短概述

Socket.io 中的命名空间和房间非常相似,最大的区别是:

  • 命名空间内有房间
  • 命名空间是在服务器端创建,并从客户端加入
  • 房间仅存在于服务器端,客户端不知道它们的存在

根据您正在构建的内容选择使用哪一个。

这里有更多细节,请参考this这篇有用的文章。

命名空间

Socket.IO允许您对套接字进行命名空间分组,这实际上意味着分配不同的端点或路径。

这是一个有用的功能,可以最小化资源数量(TCP连接),同时在通信通道之间引入分离。

命名空间是在服务器端创建的。但是,客户端通过向服务器发送请求来加入它们。(例如:io.connect('/namespace')

房间

房间是命名空间的子通道。房间纯粹是服务器端的构造,客户端对它们一无所知。

您不能使用socket io从客户端加入房间,这应该在服务器端发生。为了解决这个问题,您需要使用要加入的房间作为数据发出一个socket,并在服务器端侦听此socket并使用已发送的房间的名称或ID调用socket.join()。

0

备忘单

命名空间 房间
公共 私有
面向客户端 面向服务器端
命名空间可以包含房间 房间不能包含命名空间
最佳用例:在代码中预定义 最佳用例:动态创建

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接