如果客户端断开连接,使用ZeroMQ向特定客户端发送回复并排队

时间:2015-10-23 08:32:11

标签: zeromq pyzmq

我是ZeroMQ的新手并试图弄清楚设计问题。我的方案是我有一个或多个客户端向单个服务器发送请求。服务器将处理请求,执行一些操作,并向客户端发送回复。有两个条件:

  • 回复必须发送给发送请求的客户。
  • 如果客户端断开连接,服务器应将消息排队一段时间,以便在客户端重新连接时,它可以接收错过的消息。

我很难找到实现这一目标的最简单方法。

我尝试的事情:

  • PUB / SUB - 我可以使用主题标记回复,以确保只有发送其请求的订阅者(以其主题作为其标识符)才会收到正确的回复。这会解决路由问题,但由于发布者不知道订阅者,因此对于断开连接的客户端一无所知。

  • PUSH / PULL - 似乎能够处理消息排队问题,但看起来它不支持我将消息发送到特定客户端的计划(例如,基于他们的ID)。

  • ROUTER / DEALER - 设计似乎是两者的解决方案,但所有示例都显得相当复杂。

我现在的想法是继续使用PUB / SUB,尝试在客户端实现某种心跳(允许服务器检测客户端的存在),当客户端不再发送心跳时,它将停止发送标记有其主题的消息。但这似乎是次优的,也会涉及另一个插座。

对于我可能采取的其他方式,是否有任何想法或建议?任何信息,将不胜感激。我在Python工作,但任何语言都没问题。

1 个答案:

答案 0 :(得分:0)

为您的解决方案准备最佳建议,提供有关您的应用程序要求的更多数据。我对你的条件进行了一些研究,并将其与我对ZMQ的经验联系起来,在这里我提出了两种可能性:

1)PUSH / PULL模式双向,对可扩展性的影响更大,但来自服务器的消息将被缓存。

服务器有一个PULL套接字来注册每个客户端并从客户端获取所有消息。每条消息都应具有客户端ID,以获取发送响应的服务器知识。

对于每个客户端 - 服务器创建PUSH套接字以发送响应。套接字配置已在注册消息中发送。您还可以将REQ / REP模式用于寄存器客户端(分配套接字号)。

每个客户端都有自己的PULL套接字,该配置已通过注册消息发送到服务器。

这意味着需要三个客户端的服务器(例如[]中的端口号:

  • 服务器:1个PULL[5555]套接字,3个PUSH[5560,5561,5562]套接字(+可选1个REQ[5556]套接字用于注册,但我认为这取决于您如何准备客户端身份)
  • 客户端:1 x PUSH[5555]套接字,1 x PULL[5560|5561|5562](每个客户端一个)(+可选1 X REP[5556]

您必须将服务器连接到多个客户端套接字才能发送响应,但如果客户端断开连接,则不会丢失消息。客户端在重新连接到PULL套接字时会收到自己的消息。缺点是需要在服务器端创建少量PUSH套接字(客户端数量)。

2)PUB / SUB + PUSH / PULL或REQ / REP ,服务器端的静态cocket配置(仅限2),但服务器必须准备一些重传或缓存消息的机制。

服务器创建PUB套接字和PULLREQ。客户端通过PULLREQ套接字来注册它。服务器将使用此标识作为过滤器将所有消息发布到客户端。服务器使用monitor()套接字上的PUB功能来计算已连接和已断开连接的客户端的数量(操作:'接受'以及'断开')。在'断开'操作服务器向所有客户端发布消息以再次注册。对于未重新注册的客户端,服务器停止发布消息。

客户端创建SUB套接字和PUSHREQ以注册和发送请求。

此解决方案可能需要服务器端的一些缓存。客户端可以在从SUB套接字获取后确认每条消息。它更复杂,必须与您的要求相关联。如果你只是想知道客户丢失了消息。客户端可以在注册期间发送从服务器收到的最后一条消息的时间戳。如果您需要保证客户端获取所有消息,则需要一些缓存实现。也许其他订阅所有邮件并删除每个邮件确认的进程。

在此解决方案服务器中需要三个客户端([]中的示例端口号:

  • 服务器:1 x PUB[5555]套接字,1 x REPPULL[5560]套接字+监控PUB套接字
  • 客户端:1 x SUB[5555]套接字和自己的过滤器标识,1 x REQPUSH[5560]套接字

关于监控,你可以在这里阅读:https://github.com/JustinTulloss/zeromq.node#monitoring(NodeJS实现,但Python将类似)

我考虑其他模式,但我不确定ROUTER/DEALERREQ/REP是否会满足您的要求。您应该阅读有关模式的更多信息,因为每种模式对于某些解决方案更好。看这里: