发送消息到多个服务器pyzmq

时间:2014-07-16 18:45:14

标签: python python-2.7 sockets zeromq pyzmq

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

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")

只有一台服务器实际上会收到消息。 documentation表示pyzmq在所有可用服务器上执行一些简单的负载平衡。

有没有办法向所有服务器发送消息,而不仅仅是一个?


背景:

我正试图用我的电脑控制树莓派的网络。我需要立即向所有人发送消息,但我不能使用PUB / SUB模型,因为他们都需要回复该消息。

我有一个请求者(主计算机)向所有回复者(raspberry pis)发送请求,他们都单独回复。例如,我可以发送一条消息,要求从温度传感器获取读数,我希望所有的覆盆子pis都能读取一个温度传感器并将其发回。

4 个答案:

答案 0 :(得分:2)

使用适当的形式通信模式。

ZMQ.REQ形式主义确实期望,该组件通过发送REQUEST来询问其他进程,以响应该消息做一些工作。因此,多个exgress目标 .connect() 已建立了传输关系,以循环模式提供服务,以公平队列策略模式一个接一个地选择。因此,该组件可以用于不同的目的,而不是您要求它。

解决方案

尝试一些更复杂的正式沟通模式,即传播"消息传递给所有相关对等方(PUB / SUB)但更复杂,更智能,故障安全的派生方案,可以满足您的Raspberry PI解决方案需求。

ZeroMQ的最大优势在于它可以卸载您的低级细节,让您在设计所需的所有分布式可扩展形式通信模式时获得巨大的力量。忘掉ZeroMQ绑定中直接列出的几个原语(构建块)。考虑一下您的抽象消息/事件处理方案,然后组装ZeroMQ元素以满足该方案。

ZeroMQ [套接字]不是从A到B的软管。它是用于与智能形式通信模式节点对话的访问端口。您可能会受益,[套接字]可能同时适用于多个传输类...因此形式通信模式可能跨越通过L3网络{{1} }进入[localhost]内的[TCP:][IPC:]进程到进程通道。

所有并行工作(嗯,确定 - 一旦检查得更细,几乎并行)

所有人都在顺畅的共同整合环境中工作。

从何处采购?

你可以为此做的最好的下一步是恕我直言,以获得更多的全局视图,这对于尝试使用ZeroMQ进行编码的前几个事情听起来很复杂,但如果你至少跳转到页面Code Connected, Volume 1 [asPdf->]的265 ,如果不是那里一步一步阅读的话。

最快的学习曲线将是图60 重新发布更新 <和<<>首先显示未公开的视图 strong>图62 HA克隆服务器对可能的高可用性方法,然后回到根,元素和细节。

答案 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 :(得分:0)

使用PUB / SUB发送请求,并使用完全独立的PUSH / PULL套接字获取答案。响应消息可能应该包含一个字段,说明它来自哪个Pi。

答案 3 :(得分:-1)

我刚使用了一系列req / rep对。每个客户端都有多个req套接字,每个服务器都有一个rep套接字。这不是可扩展的解决方案吗?发送的数据不需要高可伸缩性。如果它确实存在问题,我可以使用pub / sub做一些事情。