您缺少的是经销商套接字以循环方式向任何连接的客户端发送消息。结果是你的架构不会按照你想要的方式工作。
首先,我会为您的预期架构写一个更准确的图表(目前,我忽略了套接字类型):
Client <-----> Broker ------> Receiver
^ |
| |
\ v
---------- Processor
当您发送第一条消息时,它会被发送到接收者 -因为它是队列中第一个连接的套接字。当您发送第二条消息时,DEALER
代理上的套接字以循环方式发送到队列中的下一个套接字,即第一个处理器。基本上,问题在于您的代理无法区分您的“接收器”套接字和“处理器”套接字,它将它们都视为同一事物。
有几种方法可以处理这个问题。首先,您可能并不真正需要您的“接收器”套接字作为中间人,您可能能够在代理和处理工作人员之间直接来回通信。我建议首先,因为这通常是这些类型的架构的工作方式。
您还可以向您的代理添加另一个套接字,让一个套接字发送到接收器,一个从处理器接收。
或者,您可以将DEALER
代理上的套接字替换为另一个ROUTER
套接字,这将允许您每次都直接寻址接收器套接字。
跟进,以解决您评论中的问题:
您的每个工作人员都有不同的职责,这是用套接字替换DEALER
代理上的ROUTER
套接字的一个很好的理由。
我现成的建议是围绕Majordomo 协议重新架构(可以在此处找到更高版本,并在此处的 ZMQ 指南中进行了讨论,并带有 Java 代码示例)。它完全符合您的要求,并且做得很好。
但是,在更简单的层面上,您将要做的事情如下:
- 启动你的代理,
ROUTER
在前端和后端都有套接字——这两个套接字都是bind()
-ed。
- 启动你的工人。每个工人都知道自己的责任。删除“接收器”,我们不会使用它。
connect()
你的工人做你的经纪人。
- 每个工人向代理发送一条消息,告诉代理该工人负责什么。经纪人通过 ID 记录每个工人的记录,以及该工人负责的工作。
- 当经纪人想要发送特定的工作时,它会查找负责该工作的工人,并将工作发送给它。
- 如果工作人员立即可用,它会处理它,否则它会保留该工作,直到它准备好处理它。
- 当工作人员完成后,它会将作业发回并继续处理新作业(如果有的话)。
所有这些都是 Majordomo 协议所实现的,以及其他必要的元素,比如心跳,这些元素构成了一个完整的 ZMQ 应用程序。这就是为什么我建议您直接使用该协议,如果它满足您想要完成的需求,而不是尝试构建您自己的。