向多个服务器发送消息 pyzmq

3 投票
4 回答
1619 浏览
提问于 2025-04-18 13:35

如果我有一个客户端连接到多个服务器,并尝试发送一条消息,

socket = context.socket(zmq.REQ)
socket.connect ("tcp://127.0.0.1:5565")
socket.connect ("tcp://127.0.0.1:5566")
socket.connect ("tcp://127.0.0.1:5567")
socket.send("Hello all")

那么只有一台服务器会实际收到这条消息。文档中提到,pyzmq会在所有可用的服务器之间进行一些简单的负载均衡。

有没有办法可以把消息发送给所有服务器,而不仅仅是一台呢?


背景:

我正在尝试用我的电脑控制一组树莓派。我需要一次性向它们发送消息,但我不能使用发布/订阅模型,因为那样的话它们都需要对这条消息做出回应。

我有一个请求者(主电脑),它向所有的应答者(树莓派)发送请求,然后它们各自单独回复。例如,我可以发送一条消息,询问温度传感器的读数,我希望所有的树莓派都读取温度传感器并把结果发回来。

4 个回答

-1

我刚刚使用了一组请求/回复的配对。每个客户端有多个请求的套接字,而每个服务器只有一个回复的套接字。这种方式是不是不够灵活呢?其实发送的数据并不需要很高的灵活性。如果真有问题的话,我可以考虑用发布/订阅的方式来解决。

0

另一种方法是使用 PUSH/PULL,而不是 PUB/SUB。因为在 PUB/SUB 方法中,如果一个订阅者还没有启动,你发送的消息可能会丢失。但是在 PUSH/PULL 方法中,当一个 客户端/发送者 发送消息(PUSH)时,服务器/接收者 可以随时通过 PULL 来获取这条消息。


下面是一个简单的例子:

客户端的代码片段:

import zmq

def create_push_socket(ip, port):
    print('PUB')
    context = zmq.Context()
    socket = context.socket(zmq.PUSH)
    zmq_address = "tcp://{}:{}".format(ip, port)
    socket.connect(zmq_address)
    return socket 

sock1 = create_push_socket('RPi-1-IP', RPi-1-PORT)
sock2 = create_push_socket('RPi-1-IP', RPi-1-PORT)
sock3 = create_push_socket('RPi-1-IP', RPi-1-PORT)

sock1.send('Hello')
sock2.send('Hello')
sock3.send('Hello')

服务器的代码片段:

import zmq

def listen():
    context = zmq.Context()
    zmq_ = context.socket(zmq.PULL)
    zmq_.bind('tcp://*:6667')
    print(zmq_.recv())


listen()
2

是的。

使用一个合适的正式通信模式。

ZMQ.REQ的形式确实是期待某个组件通过发送请求来询问其他进程,要求它们根据消息做一些工作。因此,多个目标通过.connect()建立的连接,会以轮询的方式进行处理,一个接一个地选择,遵循公平排队的原则。所以这个组件的工作方式和你想要它做的事情是不同的。

解决方案

尝试一些更复杂的正式通信模式,这种模式可以将消息“传播”给所有相关的节点(类似于发布/订阅),但要更复杂、更智能,并且具有故障安全的特性,以满足你的Raspberry PI解决方案的需求。

ZeroMQ的最大优势在于,它将低级细节从你身上卸载,让你在设计所需的分布式可扩展正式通信模式时拥有巨大的自由度。不要只关注ZeroMQ绑定中列出的少数基本构件(构建块)。要考虑你的抽象消息/事件处理方案,然后将ZeroMQ的元素组合起来以满足该方案。

ZeroMQ [socket]并不是从A到B的简单管道。它更像是一个与智能正式通信模式节点对话的接入端口。你可以利用这一点,因为[socket]可以同时在多种传输方式上工作……所以你的正式通信模式可以跨越L3网络[TCP:],并进入[IPC:][INPROC:]的进程间通道。

所有的工作都是并行进行的(当然,仔细检查时几乎是并行的)。

所有的工作都在一个顺畅的集成环境中进行。

从哪里获取资源?

在我看来,接下来的最佳步骤是获得一个更全面的视角,虽然一开始用ZeroMQ编码可能会觉得复杂,但如果你至少跳到《代码连接,第一卷》第265页,那将会有所帮助,哪怕不是一步一步地阅读。

最快的学习曲线是先对图60 重新发布更新图62 高可用克隆服务器对有一个初步的了解,然后再回到基础、元素和细节。

0

使用发布/订阅(PUB/SUB)模式来发送请求,然后用一个完全不同的推送/拉取(PUSH/PULL)套接字来接收回复。回复的信息里最好有一个字段,说明这个回复是来自哪个树莓派(Pi)。

撰写回答