我是ZeroMQ的新手并试图弄清楚设计问题。我的方案是我有一个或多个客户端向单个服务器发送请求。服务器将处理请求,执行一些操作,并向客户端发送回复。有两个条件:
我很难找到实现这一目标的最简单方法。
我尝试的事情:
PUB / SUB - 我可以使用主题标记回复,以确保只有发送其请求的订阅者(以其主题作为其标识符)才会收到正确的回复。这会解决路由问题,但由于发布者不知道订阅者,因此对于断开连接的客户端一无所知。
PUSH / PULL - 似乎能够处理消息排队问题,但看起来它不支持我将消息发送到特定客户端的计划(例如,基于他们的ID)。
ROUTER / DEALER - 设计似乎是两者的解决方案,但所有示例都显得相当复杂。
我现在的想法是继续使用PUB / SUB,尝试在客户端实现某种心跳(允许服务器检测客户端的存在),当客户端不再发送心跳时,它将停止发送标记有其主题的消息。但这似乎是次优的,也会涉及另一个插座。
对于我可能采取的其他方式,是否有任何想法或建议?任何信息,将不胜感激。我在Python工作,但任何语言都没问题。
答案 0 :(得分:0)
为您的解决方案准备最佳建议,提供有关您的应用程序要求的更多数据。我对你的条件进行了一些研究,并将其与我对ZMQ的经验联系起来,在这里我提出了两种可能性:
1)PUSH / PULL模式双向,对可扩展性的影响更大,但来自服务器的消息将被缓存。
服务器有一个PULL套接字来注册每个客户端并从客户端获取所有消息。每条消息都应具有客户端ID,以获取发送响应的服务器知识。
对于每个客户端 - 服务器创建PUSH套接字以发送响应。套接字配置已在注册消息中发送。您还可以将REQ / REP模式用于寄存器客户端(分配套接字号)。
每个客户端都有自己的PULL
套接字,该配置已通过注册消息发送到服务器。
这意味着需要三个客户端的服务器(例如[]中的端口号:
PULL[5555]
套接字,3个PUSH[5560,5561,5562]
套接字(+可选1个REQ[5556]
套接字用于注册,但我认为这取决于您如何准备客户端身份)PUSH[5555]
套接字,1 x PULL[5560|5561|5562]
(每个客户端一个)(+可选1 X REP[5556]
)您必须将服务器连接到多个客户端套接字才能发送响应,但如果客户端断开连接,则不会丢失消息。客户端在重新连接到PULL套接字时会收到自己的消息。缺点是需要在服务器端创建少量PUSH套接字(客户端数量)。
2)PUB / SUB + PUSH / PULL或REQ / REP ,服务器端的静态cocket配置(仅限2),但服务器必须准备一些重传或缓存消息的机制。
服务器创建PUB
套接字和PULL
或REQ
。客户端通过PULL
或REQ
套接字来注册它。服务器将使用此标识作为过滤器将所有消息发布到客户端。服务器使用monitor()
套接字上的PUB
功能来计算已连接和已断开连接的客户端的数量(操作:'接受'以及'断开')。在'断开'操作服务器向所有客户端发布消息以再次注册。对于未重新注册的客户端,服务器停止发布消息。
客户端创建SUB
套接字和PUSH
或REQ
以注册和发送请求。
此解决方案可能需要服务器端的一些缓存。客户端可以在从SUB套接字获取后确认每条消息。它更复杂,必须与您的要求相关联。如果你只是想知道客户丢失了消息。客户端可以在注册期间发送从服务器收到的最后一条消息的时间戳。如果您需要保证客户端获取所有消息,则需要一些缓存实现。也许其他订阅所有邮件并删除每个邮件确认的进程。
在此解决方案服务器中需要三个客户端([]中的示例端口号:
PUB[5555]
套接字,1 x REP
或PULL[5560]
套接字+监控PUB
套接字SUB[5555]
套接字和自己的过滤器标识,1 x REQ
或PUSH[5560]
套接字关于监控,你可以在这里阅读:https://github.com/JustinTulloss/zeromq.node#monitoring(NodeJS实现,但Python将类似)
我考虑其他模式,但我不确定ROUTER/DEALER
或REQ/REP
是否会满足您的要求。您应该阅读有关模式的更多信息,因为每种模式对于某些解决方案更好。看这里: