【问题标题】:Socket.io: Namespaces, channels & coSocket.io:命名空间、通道和合作
【发布时间】:2012-11-10 08:34:00
【问题描述】:

我有一个 Node.js Web 服务器,它在顶部运行一个套接字服务器,它是使用 Socket.io 创建的。基本上,这行得通。

我现在想要实现的是将连接的客户端聚集成组。因此,可能有一些客户端组成 A 组,而其他一些客户端则组成 B 组。它们应通过寻址特定 URL(localhost:3000/Alocalhost:3000/B)来选择属于哪个组。

在 Socket.io 中,我现在想向 A 组中的所有客户端或 B 组中的所有客户端或所有客户端发送消息,而不查看它们的组。

这基本上就像与房间聊天,您可以为特定房间内的所有客户或任何客户发送消息,无论他在哪个房间。

使用 Socket.io 设计这样一个系统的最佳方法是什么?

到目前为止,我一直在尝试使用命名空间,它基本上适用于创建组 A 和 B,但是我失去了向所有客户端发送消息的能力,无论他们在什么房间。至少我不知道如何做到这一点。

我应该如何建模?我应该寻找哪些正确的术语?

更新:根据@sdedelbrock 的回答,我可以使用命名空间或房间:

  • 如果使用命名空间,我无法长时间发送给每个人,无论他们的命名空间如何。这是因为io.socketsio.of('') 的快捷方式,当然它不再匹配命名空间。
  • 这意味着我应该使用房间,但我想知道房间和命名空间之间的语义区别是什么。

简而言之:为什么同一个 (?) 想法有两个概念?

【问题讨论】:

    标签: node.js namespaces socket.io channel


    【解决方案1】:

    您可能正在使用房间,因此您将执行以下操作以向房间中的每个人发射

    io.sockets.in('a').emit('inA', 'foo')
    

    然后发射给你可以使用的每个人

    io.sockets.emit('everyone','bar');
    

    您也可以使用命名空间:

    io.of('/b').emit('inB', 'buzz');
    

    要向除触发您的用户之外的所有人发出信号:

    io.sockets.broadcast.emit("hello");
    

    [编辑] 这是一个更详细的答案:

    name-spacing 背后的想法是,它与其他命名空间(甚至是全局命名空间)分开处理。把它想象成一个全新的 socket.io 实例,你可以运行新的握手、新的事件、授权等,而不同的命名空间不会相互干扰。

    这对于说/chat/tracking 很有用,其中连接事件的逻辑非常不同

    Socket.io 为您完成所有工作,就好像它是两个独立的实例一样,但仍将信息限制在一个连接中,这非常聪明。

    可能有一种解决方法,您可以在其中广播到所有命名空间(下面的示例)。但简而言之,您不应该这样做,您应该使用房间。

    for (var nameSpace in io.sockets.manager.namespaces){
      io.of(nameSpace).emit("messageToAll", message);
    }
    

    【讨论】:

    • 我试过这个。当使用第二种方法(命名空间)时,无论他们的命名空间如何,我都无法长时间发送给每个人。这是因为io.socketsio.of('') 的快捷方式,当然它不再匹配命名空间。所以这意味着我应该使用房间。无论如何,我想知道房间和命名空间之间的语义区别是什么?为什么同一个 (?) 想法有两个概念?
    • 我相信这样可以将它们分开管理,尽管Socket.io Namespaces 我确实找到了一篇很好的文章
    • 这篇文章绝对是一本好书,可惜它没有回答我的问题。我仍然不明白什么时候应该使用命名空间,什么时候使用房间,以及它们之间的语义差异是什么。此外:我如何向所有客户端发送消息,而不管它们的命名空间如何?
    • 你好@Golo Roden,有点晚了,但我现在已经遇到了。我认为简而言之,房间应该用于处理不同地方的套接字上的相同行为(聊天室最简单的例子)但命名空间应该用于跟踪不同的事物,例如实时新闻提要与聊天室。希望为任何人增添更多的光芒。感谢您的提问和回答!
    • 这个io.sockets.broadcast.emit 不正确,broadcast 需要知道要排除/忽略哪个套接字ID,因此您有两个选择:1)来自全局 io -> io.sockets.in(namespace).socket(socketID).broadcast.emit("hello") 或 2)来自套接字->socket.broadcast.emit("hello")
    【解决方案2】:

    这是您可以使用的模板应用程序(适用于 9.16;未在 1.x 上测试,但应该可以使用):

    var namespaces = [
        io.of('/ns1'),
        io.of('/ns2'),
        io.of('/ns3')
    ];
    
    for (i in namespaces) {
        namespaces[i].on('connection',handleConnection(namespaces[i]));  
    }
    
    function handleConnection(ns) {
       return function (socket){ //connection
       console.log("connected ");
       socket.on('setUsername',setUsernameCallback(socket,ns));                       
       socket.on('disconnect', disconnectCallback(socket,ns));                        
       socket.on('messageChat',messageChatCallback(socket,ns));
       socket.on('createJoinRoom',createJoinRoomCallback(socket,ns));  
    
      };
    }
    
    function disconnectCallback(socket,ns) {
        return function(msg){
        console.log("Disconnected ");
        socket.broadcast.send("It works!");
      };
    }
    

    你可以自己写其他句柄:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-11
      • 2012-10-20
      • 2018-06-10
      • 1970-01-01
      • 2021-02-27
      • 2011-11-26
      • 2014-12-11
      相关资源
      最近更新 更多