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

And*_*bie 5 zeromq pyzmq

我是ZeroMQ的新手,正在尝试找出设计问题。我的情况是,我有一个或多个客户端将请求发送到单个服务器。服务器将处理请求,进行一些处理,然后将回复发送给客户端。有两个条件:

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

我很难确定实现此目的的最简单方法。

我尝试过的事情:

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

  • 推/拉-似乎能够处理消息排队问题,但似乎不支持我的将消息发送给特定客户端的计划(例如,基于其ID)。

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

我现在的想法是继续使用PUB / SUB,尝试在客户端上实现某种心跳(允许服务器检测到客户端的存在),并且当客户端不再发送心跳时,它将停止发送标记为的消息。它的主题。但这似乎不是最佳选择,并且还会涉及另一个套接字。

关于实现此目标的其他方式是否有任何想法或建议?任何信息,将不胜感激。我正在使用Python工作,但是任何语言都可以。

Mic*_* P. 2

要为您的解决方案准备最佳建议,请提供有关您的应用程序要求的更多数据。我对你的情况做了一些研究,并结合我对ZMQ的经验,在这里我提出两种可能性:

1)两个方向的PUSH/PULL模式,对可扩展性影响较大,但来自服务器的消息会被缓存。

服务器有一个 PULL 套接字来注册每个客户端并获取来自客户端的所有消息。每条消息都应该有客户端 ID,以便服务器知道在哪里发送响应。

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

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

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

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

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

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

服务器创建PUB套接字和PULLREQPULL客户端通过或套接字注册它的身份REQ。服务器将以此身份作为过滤器向客户端发布所有消息。服务器使用套接字monitor()上的函数PUB来计算连接和断开连接的客户端数量(操作:“接受”和“断开连接”)。在“断开连接”操作之后,服务器向所有客户端发布消息以重新注册。对于没有重新注册的客户端,服务器停止发布消息。

客户端创建SUB套接字和PUSH/或REQ来注册和发送请求。

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

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

  • 服务器:1 xPUB[5555]套接字,1 xREPPULL[5560]套接字+监控PUB套接字
  • 客户端:1 xSUB[5555]套接字和过滤器自己的身份,1 xREQPUSH[5560]套接字

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


我考虑了其他模式,但我不确定是否ROUTER/DEALERREQ/REP满足您的要求。您应该阅读更多有关模式的内容,因为每种模式都适合某些解决方案。看这里: