ZeroMQ:如何构建简单的异步代理?似乎不可能 [英] ZeroMQ: How to construct simple asynchronous broker? Seems impossible

查看:60
本文介绍了ZeroMQ:如何构建简单的异步代理?似乎不可能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am building a simple star-like client-server topology.

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

The idea is that clients connect to the server, can send messages, and the server can send messages to them, when the server decides to. There will be a relatively small number of clients, about 30, but so many that it is not sensible to send all outgoing data to all. I'm sure I'm just boneheaded, but this seems to be completely impossible with ZeroMQ.

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

The last part is the reason this question does not provide answer.

问题是这样的:

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

I can use a ROUTER socket to receive messages from clients. This also carries identification. However, I cannot use the same socket for sending, since ZeroMQ sockets are not threadsafe. I.e. I can't have one thread waiting for incoming messages, and another sending outgoing from the server itself. I am not aware of any way I could wait in blocking for both - socket.recv(), and for example .get() on a queue - at the same time on a single thread in python. Maybe there is a way to do that.

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

Using two sockets - one incoming one outgoing - doesn't work either. The identification is not shared between sockets, and so the sending socket would still have to be polled to obtain client id mapping, if even for once. We obviously can't use own port for each client. There seems to be no way for the server to send a message to a single client out of it's own volition.

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

(subscription topics are a dead idea too: message filtering is performed on client-side, and the server would just flood all client networks)

最终,TCP 套接字可以轻松处理这种异步情况,但是在 Python 上构建有效的消息框架是一场噩梦.我基本上只需要一个可靠的套接字来处理消息,并具有明确定义的故障模式.

In the end TCP sockets can handle this sort of asynchronous situation easily, but effective message framing on python is a nightmare to build. All I'm essentially after is a reliable socket that handles messages, and has well defined failure modes.

推荐答案

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

I don't know Python but for C/C++ I would use zmq_poll(). There are several options, depending on your requirements.

  • 使用 zmq_poll() 等待来自客户端的消息.如果消息到达,则对其进行处理.也使用超时.超时到期后,请检查您是否需要向客户端发送消息并发送.
  • zmq_poll() 也可以等待通用文件描述符.当您有消息要发送到客户端时,您可以使用某种类型的文件描述符并从另一个进程或线程触发它(写入它).如果触发此文件描述符,则向客户端发送消息.
  • 在服务器内部使用 ZeroMQ 套接字.使用 zmq_poll() 等待来自客户端和内部进程或线程的消息.如果触发了内部套接字,则向客户端发送消息.
  • Use zmq_poll() to wait for messages from clients. If a message arrives, process it. Also use a time-out. When the time-out expires, check if you need to send messages to clients and send them.
  • zmq_poll() can also wait on general file descriptors. You can use some type of file descriptor and trigger it (write to it) from another process or thread when you have a message to send to a client. If this file descriptor is triggered, send messages to clients.
  • Use ZeroMQ sockets internally inside your server. Use zmq_poll() to wait both on messages from clients and internal processes or threads. If the internal sockets are triggered, send messages to clients.

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

You can use the file descriptor or internal ZeroMQ sockets just for triggering but you can also send the message content through the file descriptor or ZeroMQ socket.

这篇关于ZeroMQ:如何构建简单的异步代理?似乎不可能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆