2012-11-22 19 views
28

我有一个Node.js网络服务器,它运行顶层的套接字服务器,它使用Socket.io创建。基本上,这是有效的。Socket.io:Namespaces,channels&co

我现在想要实现的是,连接的客户端是按群组聚集的。因此,可能有一些客户组成了组A以及组成组B的一些其他客户。他们应该通过对特定的URL(localhost:3000/Alocalhost:3000/B)进行选择来选择他们属于哪个组。

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

它基本上就像带客房的聊天,你必须对所有客户端或者消息的特定的房间内,或任何客户端,不管他在哪个房间。

什么是设计最好的办法这样的系统使用Socket.io?

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

我该如何建模?我应该寻找什么样的正确条款?

UPDATE:@sdedelbrock答案我可以使用命名空间或房间:

  • 如果使用命名空间,我没多久能够发送到每个人,不论其命名空间。这是因为io.socketsio.of('')的快捷方式,当然这与命名空间不再匹配。
  • 这意味着我应该使用房间,但我不知道房间和名称空间之间的语义差异是什么。

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

回答

29

你可能会使用的房间,所以你会做以下发出来大家都在一个房间里

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

然后发出来大家就可以使用

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

您也可以使用名字空间好:

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

要发射给除触发您将使用的用户外的所有人:

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

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

背后名称间距的想法是,它是从其他命名空间(甚至全球)分开处理。把它看作是一个全新的socket.io实例,你可以运行新的握手,新事件,授权等,而不会有不同的名称空间相互干扰。

这将为发言权/chat/tracking其中连接事件将具有非常不同的逻辑是有用的

Socket.io为您完成所有的工作,就好像它是两个单独的实例,但仍限制了信息传递给一个连接,这非常聪明。

可能有一种解决方法,您可以在其中向所有名称空间进行广播(以下示例)。但总之你不应该这样做,你应该使用房间。

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

我试过这个。当使用第二种方法(名称空间)时,无论名称空间如何,我都无法发送给每个人。这是因为'io.sockets'是'io.of('')'的快捷方式,当然这与命名空间不再匹配。所以这意味着我应该使用房间。 无论如何,我不知道房间和命名空间之间的语义差异是什么?为什么同一个(?)想法有两个概念? –

+1

我相信这是它们可以单独管理,但我确实发现了一个很好的写法[Socket.io Namespaces](http://gordonkoo.com/blog/2012/02/28/under-the-hood -of-socket-io-namespaces /) – Sdedelbrock

+0

这篇文章绝对是一个很好的阅读,但不幸的是它不能回答我的问题。我仍然不明白何时应该使用名称空间,何时使用空间,以及它们之间的语义差异。另外:我如何向所有客户端发送消息,而不管他们的名称空间如何? –

4

这是你可以使用模板的应用程序(适用于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!"); 
    }; 
} 

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