首页 > 解决方案 > ZeroMQ:如何构造简单的异步代理?似乎不可能

问题描述

我正在构建一个简单的星型客户端-服务器拓扑。

这个想法是客户端连接到服务器,可以发送消息,并且服务器可以在服务器决定时向它们发送消息。客户端的数量相对较少,大约 30 个,但数量太多,将所有传出数据发送给所有人是不明智的。我敢肯定我只是头脑简单,但这对于 ZeroMQ 来说似乎是完全不可能的。

最后一部分是这个问题没有提供答案的原因。

问题是:

我可以使用ROUTER套接字来接收来自客户端的消息。这也带有身份证明。但是,我不能使用同一个套接字进行发送,因为 ZeroMQ 套接字不是线程安全的。即,我不能让一个线程等待传入消息,而另一个线程则从服务器本身发送传出消息。我不知道有什么方法可以等待阻塞 - socket.recv(),例如.get()在队列上 - 同时在 python 中的单个线程上。也许有办法做到这一点。

使用两个套接字——一个传入一个传出——也不起作用。标识不会在套接字之间共享,因此即使只有一次,仍必须轮询发送套接字以获取客户端 ID 映射。我们显然不能为每个客户端使用自己的端口。服务器似乎无法出于自己的意愿向单个客户端发送消息。

(订阅主题也是一个死主意:消息过滤在客户端执行,服务器只会淹没所有客户端网络)

最后,TCP 套接字可以轻松处理这种异步情况,但是在 python 上构建有效的消息框架是一场噩梦。我所追求的只是一个处理消息的可靠套接字,并且具有明确定义的故障模式。

标签: pythonasynchronousnetworkingzeromq

解决方案


我不知道 Python,但对于 C/C++,我会使用zmq_poll(). 有多种选择,具体取决于您的要求。

  • 用于zmq_poll()等待来自客户端的消息。如果消息到达,则对其进行处理。也使用超时。当超时到期时,检查是否需要向客户端发送消息并发送它们。
  • zmq_poll()也可以等待一般文件描述符。当您有消息要发送给客户端时,您可以使用某种类型的文件描述符并从另一个进程或线程触发(写入)它。如果触发此文件描述符,则向客户端发送消息。
  • 在服务器内部使用 ZeroMQ 套接字。用于zmq_poll()等待来自客户端和内部进程或线程的消息。如果内部套接字被触发,则向客户端发送消息。

您可以使用文件描述符或内部 ZeroMQ 套接字仅用于触发,但您也可以通过文件描述符或 ZeroMQ 套接字发送消息内容。


推荐阅读