我正在使用 PyZMQ 创建请求/回复服务器,并且我试图弄清楚为每个新客户端连接创建线程的行为是否由 PyZMQ 自动处理。最终,我试图弄清楚来自一个客户端的请求需要很长时间才能回复,是否会阻止来自所有其他客户端的请求。
通常,我会在 Python 套接字实例上调用accept,阻塞直到建立新连接,并在单独的线程中处理任何新连接。然而,PyZMQ 套接字似乎不支持这样的工作流程。那么,PyZMQ 中是如何处理的呢?如果 PyZMQ REP 套接字有多个客户端连接到它,它如何正确地将回复路由回发出请求的客户端?而且,我如何设计我的代码,以便当客户端发出长时间运行的请求时,来自其他客户端的请求不会被阻止?
我知道我可以使用 PyZMQ 提供的基于 Tornado 的 EventLoop,我只是想更好地理解如果这不是一个选项的话它将如何工作。
ZeroMQ 被公开为“类固醇套接字”,但还有另一种实现通信的方法。
首先,忘记传统套接字中连接对等点的电线。在 0mq 中,您有一个“量子传送器”,它将您的消息从一段代码传递到另一段代码,对您隐藏实际的传递工作。您不能只询问 0mq 有多少客户端连接到套接字或是否有客户端。因此,ZeroMQ 不能用作套接字的直接替代品。
相反,0mq 会给你一顶魔术师帽子,你可以从中拿走一些小白兔。想象一下,帽子的底部与一个巨大的管道网络相连,另一侧有多个工厂,生产着奇妙的东西。这些工厂有时会寄一些东西到你的帽子上,当你从帽子里拿出来时,你会发现自己手里拿着一只兔子,或者一束鲜花或其他东西。您无法确定该物品是从哪个工厂发送的,除非该物品上有明确的标签(即多部分消息的一部分指向消息的来源)。
在你从帽子里取出兔子后,你可能想发回一些东西,0mq 对于不同的套接字类型会有不同的行为。对于 REP 套接字,它将直接向消息源发送应答,对于 DEALER 来说,它将在连接的对等点之间循环应答,而 ROUTER 在接收消息时让您了解对等点的确切内部地址,并允许您在发送消息时设置显式目的地。
总而言之,如果您希望每个通信客户端都有一个单独的线程,则需要以下内容:
- 客户应明确表明自己的身份。
- 在服务器上,您运行一个线程(调度程序)来接收消息,从中获取客户端身份并选择一个线程进行处理。
- 调度程序将此消息发送到线程(或生成一个线程)并继续为传入消息流提供服务。
- 线程接收消息,处理它并通过调度程序将答案发送给客户端(如果需要)。
- 调度程序将应答路由给客户端。
这是一种利用经典套接字知识实现“zeromq 上的多客户端套接字服务器”的方法。
但这不是解决问题的 0mq 方法。
在 0mq 中,您可以将处理逻辑放在一个线程中(上面示例中的调度程序)并将其实现为一个循环receive request -> process -> send answer -> receive ...
。当处理时间不成问题时,非常适合。但当它出现时,0mq 式的解决方案涉及客户端和工作人员(执行实际工作)之间的任务队列代理。然后,代理逻辑比上面提到的接收-应答循环稍微复杂一些,并且工作器以相同的方式实现。请参阅 zguide 中的示例 -请求-回复消息代理 http://zguide2.zeromq.org/py%3aall#toc53
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)