我有一个运行顶部套接字服务器的Node.js Web服务器,它是使用Socket.io创建的。基本上,这是有效的。
我现在想要实现的是连接的客户端群组成群集。因此,可能有一些客户构成A组,其他一些客户构成B组。他们应通过寻址特定网址localhost:3000/A
或localhost:3000/B
来选择他们所属的组。
在Socket.io中,我现在想要向A组中的所有客户端或B组中的所有客户端或所有客户端发送消息,而不是查看他们的组。
这基本上就像与房间聊天一样,无论他在哪个房间,您都可以为特定房间内的所有客户或任何客户提供消息。
使用Socket.io设计此类系统的最佳方法是什么?
到目前为止,我一直在尝试使用命名空间,这基本上可以用于创建组A和B,但是我失去了向所有客户端发送消息的能力,无论他们在哪个房间。至少我不知道怎么做。
我该如何塑造这个?我应该寻找哪些合适的术语?
更新:根据@sdedelbrock的答案,我可以使用命名空间或房间:
io.sockets
是io.of('')
的快捷方式,当然这不再与命名空间相匹配。简而言之:为什么同一个(?)想法有两个概念?
答案 0 :(得分:30)
你可能正在使用房间,所以你会做以下事情向房间里的每个人发射
io.sockets.in('a').emit('inA', 'foo')
然后发给你可以使用的每个人
io.sockets.emit('everyone','bar');
您也可以使用名称空间:
io.of('/b').emit('inB', 'buzz');
要向除触发您的用户以外的所有人发出以下内容:
io.sockets.broadcast.emit("hello");
[edit]以下是更详细的解答:
名称间距背后的想法是它与其他命名空间(甚至全局)分开处理。可以把它想象成一个全新的socket.io实例,你可以运行新的握手,新事件,授权等,而不会让不同的命名空间相互干扰。
这对于说/chat
和/tracking
有用,其中连接事件具有非常不同的逻辑
Socket.io为您完成所有工作,就好像它是两个独立的实例,但仍然将信息限制为一个连接,这非常聪明。
可能有一种解决方法,您可以在其中广播所有命名空间(例如下面的示例)。但总之,你不应该这样做,你应该使用房间。
for (var nameSpace in io.sockets.manager.namespaces){
io.of(nameSpace).emit("messageToAll", message);
}
答案 1 :(得分: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!");
};
}
你可以自己写其他句柄:)