PyZMQ是否处理为每个新客户端连接创建线程?

时间:2012-10-29 15:11:04

标签: zeromq pyzmq

我正在使用PyZMQ来创建请求/回复服务器,我正在尝试弄清楚为每个新客户端连接创建线程的行为是否由PyZMQ自动处理。最后,我试图弄清楚来自一个需要很长时间才能回复的客户端的请求是否会阻止来自所有其他客户端的请求。

通常,我会在Python套接字实例上调用accept,阻塞直到建立新连接,并在单独的线程中处理任何新连接。但是,PyZMQ套接字似乎不支持这样的工作流程。那么,在PyZMQ中如何处理?如果PyZMQ REP套接字连接了多个客户端,它如何正确地将回复路由回发出请求的客户端?而且,我如何设计我的代码,以便在客户端发出长时间运行的请求时不阻止来自其他客户端的请求?

我知道我可以使用PyZMQ提供的基于Tornado的EventLoop,我只是想更好地理解它是如何工作的,如果那不是一个选项。

1 个答案:

答案 0 :(得分:4)

ZeroMQ暴露为“类固醇上的插座”,但还有另一种实现通信的方法。

首先,忘记在传统套接字中链接同伴的电线。在0mq中,您有一个“量子传送器”,它将您的消息从一段代码传递到另一段代码,从而隐藏您的实际传送工作。您不能只询问0mq有多少客户端连接到套接字,或者您是否有客户端。因此,ZeroMQ不能用作套接字的替代品。

相反,0mq会给你一个魔术师的帽子,你可以从中取一些白兔。想象一下,那顶帽子的底部与一个巨大的管道网络相连,另一边有多个奇妙的工厂。这些工厂有时候会把一些东西送到你的帽子里,当你从帽子里拿出来时,你会发现自己手里拿着一只兔子,或是一束鲜花或其他东西。除非在该事物上有明确的标签(即多部分消息的一部分指向消息的来源),否则您无法确定从哪个工厂发送了该事物。

从帽子中取出兔子之后,你可能想要发回一些东西,而对于不同的套接字类型,0mq的行为会有所不同。对于REP套接字,它将直接向消息的来源发送答案,因为DEALER将在连接的对等体上循环答案,并且ROUTER在接收消息时为您提供对等体的确切内部地址的巨大知识,并允许您在发送消息时设置显式目的地。

总结一下,如果你想为每个通信客户端提供一个单独的线程,你需要做以下事情:

  • 客户应明确表明身份。
  • 在服务器上运行一个接收消息的线程(调度程序),从中获取客户端标识并选择一个线程进行处理。
  • Dispatcher将此消息发送给线程(或生成一个)并继续提供传入消息流。
  • 线程接收消息,处理消息并通过调度程序将答案发送给客户端(如果需要)。
  • Dispatcher路由回答客户端。

这是一种在zeromq上实现“多客户端套接字服务器”的方法,并考虑到经典套接字知识。

但对于这个问题,这不是一个0mq的方法。

在0mq中,您可以将处理逻辑放在一个线程中(上例中的调度程序)并将其实现为循环receive request -> process -> send answer -> receive ...。当处理时间不是问题时,完美适合。但是当它出现时,0mq风格的解决方案涉及客户端和工作者之间的任务队列代理(执行实际工作)。然后,代理逻辑比上面提到的接收应答循环稍微复杂一点,并且工作者以相同的方式实现。请参阅zguide中的示例 - A Request-Reply Message Broker