为啥我的客户端应该只连接到一个子节点集群工作人员时接收来自所有子节点集群工作人员的套接字发射?

Posted

技术标签:

【中文标题】为啥我的客户端应该只连接到一个子节点集群工作人员时接收来自所有子节点集群工作人员的套接字发射?【英文标题】:Why is my client receiving socket emits from all child node cluster workers when it should only be connected to one?为什么我的客户端应该只连接到一个子节点集群工作人员时接收来自所有子节点集群工作人员的套接字发射? 【发布时间】:2015-04-28 01:52:14 【问题描述】:

我正在尝试使用 node.js、express、socket.io、cluster、socket.io-adapter-mongo 和 mubsub 创建一个可扩展的套接字连接处理程序。这是我第一次尝试使用套接字,所以如果我在这里暴露我的菜鸟,请原谅我,但我的理解是集群工作人员只能向连接到它的套接字发出。

在我的开发环境中,我有集群分叉 8 个工作人员(CPU 数量)。

我让我的工作人员订阅了 mubsub db,以便他们接收从其他工作人员发布的事件。

if (cluster.isMaster) 

    var cpuCount = require("os").cpus().length;
    for (var cp = 0; cp < cpuCount; cp++) 
        cluster.fork();
    
 else 

    io.adapter(mongo( host: 'localhost', port: 27017, db: 'mubsub' ));

    var client = mubsub('mongodb://localhost:27017/mubsub');

    var channel = client.channel('test');

    channel.subscribe('testEvent', function (message) 
        console.log(message);
        io.sockets.emit('testEvent', message: cluster.worker.id);
    );

    io.sockets.on('connection', function (socket) 
        console.log('connected to ' + cluster.worker.id);
        channel.publish('testEvent',  message: 'connection3' );
    );

    ...

    server.listen(8080);

因此,当我尝试从客户端连接时,会触发“连接”事件,并且接收连接的工作人员会写入单个控制台日志。

该事件仅发布到数据库一次。

每个工作人员都订阅了该事件,并且应该向连接到该工作人员的所有套接字发出。

但由于某种原因,我连接的客户端收到了 8 条消息,每个工人一条。

客户端如何从不应连接到的工作人员那里获取发射?我在这里忽略了一些集群魔法吗?

【问题讨论】:

所有工作人员都订阅了test 频道,对吧?因此,当您拨打channel.publish('testEvent', ...) 时,他们都应该收到testEvent io.sockets.emit 将发送给所有客户端 @Ben - 是的,我希望所有工作人员都接收 testEvent 并向连接到他们的所有客户端发出,我不明白为什么每个工作人员都能够向客户端发出大概只连接到一个工人。 @akonsu - 当我控制台记录连接事件中的工作人员 ID 时,它显示“连接到 3”(或 1 到 8 之间的某个数字),这让我相信客户端只连接给一名工人,但其他 7 名工人正在向鲍泽排放。他们是否可以通过集群访问其他工作套接字连接? 工人使用io.sockets,它拥有所有的连接。工人可以通过io.sockets 访问其他工人的连接,是的。 【参考方案1】:

不确定您使用的是什么版本,但对于大多数当前版本来说应该是这样。

来自 socket.io 文档 (http://socket.io/docs/server-api/#server#emit):

Server#emit
Emits an event to all connected clients. The following two are equivalent:

 var io = require('socket.io')();
 io.sockets.emit('an event sent to all connected clients');
 io.emit('an event sent to all connected clients');

因此,您使用的方法将广播到所有连接的客户端。如果您想将它们分配给工作人员,这是您需要管理的。

有多种方法可以解决 socket.ios API 可以帮助您解决的单个套接字(客户端)问题,但最好参考文档:

http://socket.io/docs/rooms-and-namespaces/

【讨论】:

以上是关于为啥我的客户端应该只连接到一个子节点集群工作人员时接收来自所有子节点集群工作人员的套接字发射?的主要内容,如果未能解决你的问题,请参考以下文章

使用 websocket 进行节点集群

如何避免只连接到 ActiveMQ 中的一个代理?

ejabberd 节点的集群如何工作?

如何将两个父节点连接到一个子节点以及如何务实地为树中的每个节点制作工具提示?在 D3 js (SVG) 中

从 WCF 连接到 MySQL 集群

Docker的mysql集群节点可以正常创建,但无法正常连接到宿主机的mysql应该如何解决?