node.js Socket.io:命名空间、通道和合作
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13504320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Socket.io: Namespaces, channels & co
提问by Golo Roden
I have a Node.js web server that runs a socket server on top, which was created using Socket.io. Basically, this works.
我有一个 Node.js Web 服务器,它在顶部运行一个套接字服务器,它是使用Socket.io创建的。基本上,这是有效的。
What I now want to achieve is that the clients that connect are clustered in groups. So there might be some clients which make up group A and some other clients which make up group B. They shall select to which group they belong by adressing a specific URL, either localhost:3000/Aor localhost:3000/B.
我现在想要实现的是连接的客户端聚集在组中。所以可能有一些客户从而弥补了A组和其他一些客户从而弥补了B组,他们将选择哪个组由他们一adressing特定的URL,无论是属于localhost:3000/A或localhost:3000/B。
In Socket.io I now want to send messages to all clients in group A or to all clients in group B or to all clients, without looking at their group.
在 Socket.io 中,我现在想向 A 组中的所有客户端或 B 组中的所有客户端或所有客户端发送消息,而无需查看它们的组。
It's basically like having a chat with rooms, and you have either messages for all clients within a specific room, or for any client, no matter what room he is in.
这基本上就像与房间聊天一样,您可以为特定房间内的所有客户或任何客户发送消息,无论他在哪个房间。
What is the best way to design such a system using Socket.io?
使用 Socket.io 设计这样一个系统的最佳方法是什么?
I have been trying using namespace so far, which basically works for creating groups A and B, but then I lose the ability to send messages to all clients, no matter what room they are in. At least I don't know how to do this.
到目前为止,我一直在尝试使用命名空间,它基本上适用于创建组 A 和 B,但随后我失去了向所有客户端发送消息的能力,无论他们在哪个房间。至少我不知道该怎么做这个。
How should I model this? What are the right terms I should look for?
我应该如何建模?我应该寻找哪些正确的术语?
UPDATE:According to the answer of @sdedelbrockI could use namespace or rooms:
更新:根据@sdedelbrock的回答,我可以使用命名空间或房间:
- If use namespaces, I am not long able to send to everybody, regardless of their namespace. This is because
io.socketsis a shortcut toio.of(''), which of course does not match the namespace any longer. - This means that I should use rooms, but I wonder what the semantic difference between a room and a namespace is.
- 如果使用命名空间,无论他们的命名空间如何,我都无法发送给所有人。这是因为
io.sockets是 的快捷方式io.of(''),当然不再匹配命名空间。 - 这意味着我应该使用房间,但我想知道房间和命名空间之间的语义区别是什么。
To cut it short: Why are there two concepts for the same (?) idea?
简而言之:为什么同一个(?)想法有两个概念?
回答by Sdedelbrock
You could be using rooms so you would do the following to emit to everybody in a room
您可以使用房间,因此您可以执行以下操作以向房间中的每个人发送
io.sockets.in('a').emit('inA', 'foo')
Then to emit to everybody you can use
然后发送给你可以使用的每个人
io.sockets.emit('everyone','bar');
You can also use namespaces as well:
你也可以使用命名空间:
io.of('/b').emit('inB', 'buzz');
To emit to everyone except the user that triggered you would use:
要发送给除触发用户之外的所有人,您可以使用:
io.sockets.broadcast.emit("hello");
[edit] Here is a more detailed answer:
[编辑] 这是一个更详细的答案:
The idea behind name-spacing is that it is handled separately from the other namespaces (even global). Think of it as if it was an entirely new socket.io instance, you can run new handshakes, fresh events, authorizations, etc without the different namespaces interfering with each other.
命名空间背后的想法是它与其他命名空间(甚至全局)分开处理。把它想象成一个全新的 socket.io 实例,你可以运行新的握手、新事件、授权等,而不同的命名空间相互干扰。
This would be useful for say /chatand /trackingwhere the connection event would have very different logic
这将为说是有用的/chat,并/tracking在连接时会有非常不同的逻辑
Socket.io does all the work for you as if it is two separate instances, but still limits the information to one connection, which is pretty smart.
Socket.io 为您完成所有工作,就好像它是两个独立的实例,但仍将信息限制为一个连接,这非常聪明。
There might be a workaround in which you can broadcast to all the namespaces (example below). However in short you shouldn't be doing this, you should be using rooms.
可能有一种解决方法,您可以在其中广播到所有命名空间(下面的示例)。但是简而言之,您不应该这样做,您应该使用房间。
for (var nameSpace in io.sockets.manager.namespaces){
io.of(nameSpace).emit("messageToAll", message);
}
回答by Marwen Trabelsi
This is a template application you can use (works for 9.16; not tested on 1.x but it should work):
这是您可以使用的模板应用程序(适用于 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!");
};
}
You could write other handles by yourself :)
你可以自己写其他句柄:)

