Python pyzmq同时发送到多个客户端
我有一个Raspberry Pi客户端和4个Raspberry Pi服务器。我希望客户端同时向所有4台服务器发送字符串消息以捕获图像。现在,我正在按顺序使用如下内容Python pyzmq同时发送到多个客户端,python,networking,raspberry-pi,pyzmq,Python,Networking,Raspberry Pi,Pyzmq,我有一个Raspberry Pi客户端和4个Raspberry Pi服务器。我希望客户端同时向所有4台服务器发送字符串消息以捕获图像。现在,我正在按顺序使用如下内容 socket.send(capture) socket1.send(capture) socket2.send(capture) socket3.send(capture) 更改为类似于发布/订阅模式会提高客户端接收消息的距离吗?我希望4个客户端在5毫秒或更短的时间内收到捕获消息。欢迎来到Zen of Zero: 虽然我们获得零保
socket.send(capture)
socket1.send(capture)
socket2.send(capture)
socket3.send(capture)
更改为类似于发布/订阅模式会提高客户端接收消息的距离吗?我希望4个客户端在5毫秒或更短的时间内收到捕获消息。欢迎来到Zen of Zero:
虽然我们获得零保修,但我们可能会在适当的方向上采取一些措施。如果您是ZeroMQ新手,请在深入了解更多详细信息之前,随意阅读其中的一些内容,至少是“”:
客户端代码概念模板:
导入zmq;打印(zmq.zmq_version())#INF:
aCtx=zmq.Context(4)#请求4个I/O线程
aPUB=aCtx.socket(zmq.PUB)#PUB实例
aPUB.setsockopt(zmq.LINGER,0)#避免关闭时死锁
aPUB.setsockopt(zmq.SNDBUF,3*PayLoadSIZE)#全高清~6MB,4K~。。。
aPUB.setsockopt(zmq.SNDHWM,aNumOfPicsInQUEUE)#1,~3~10?, !1000 ...
aPUB.setsockopt(zmq.IMMEDIATE,1)#忽略L1/L2不完整
aPUB.setsockopt(zmq.CONFLATE,1)#不要重新发送“旧的”
aPUB.bind(:)#tcp:?udp多播?
#-----------------------------------------------------------------------------[RTO]
#可能需要设置aPayLOAD=gzip.compress(dill.dumps(capture),compressionLEVEL)
#减少了序列化数据的大小
#每侧的成本约为30~60[ms]
#这可能会降低网络流量和.SNDBUF大小问题
#----------------------------------------------------------------------
而:
尝试:
aPUB.send(aPayLOAD,zmq.NOBLOCK)
除:
#按照错误号处理。。。
最后:
通过
#----------------------------------------------------------------------
aPUB.close()
aCtx.术语()
服务器代码概念模板:
导入zmq;打印(zmq.zmq_version())#INF:
aCtx=zmq.Context()#请求4个I/O线程
aSUB=aCtx.socket(zmq.SUB)#子实例
aSUB.setsockopt(zmq.LINGER,0)#在关闭时避免死锁
aSUB.setsockopt(zmq.RCVBUF,3*PayLoadSIZE)#全高清~6MB,4K~。。。
aSUB.setsockopt(zmq.RCVHWM,aNumOfPicsInQUEUE)#1,~3~10?, !1000 ...
aSUB.setsockopt(zmq.IMMEDIATE,1)#忽略L1/L2不完整
aSUB.setsockopt(zmq.CONFLATE,1)#不重新记录“旧”
aSUB.setsockopt(zmq.SUBSCRIBE,“”)#请订阅任何内容
aSUB.connect(:)#tcp:?udp多播?
#-----------------------------------------------------------------------------[RTO]
而:
尝试:
如果(aSUB.poll(zmq.POLLIN,0)=0):
#接收队列中没有准备好发送到-.recv()的内容
#睡眠()
#做一些系统工作等
其他:
aPayLOAD=aSUB.recv(zmq.NOBLOCK)
#--------------------------------------------------------
#解压缩/反序列化原始对象
#capture=dill.load(gzip.decompress(aPayLOAD))
#--------------------------------------------------------
#处理数据:
# ...
除:
#按照错误号处理。。。
最后:
通过
#----------------------------------------------------------------------
aSUB.close()
aCtx.术语()
您可以使用发布/订阅模式。您的客户端将绑定到一个IP:端口,您的服务器将连接到客户端IP:端口,并为筛选器设置一个空字符串(请检查文档),然后客户端将发布一个字符串。此消息将同时发送到所有订阅的服务器。一旦服务器收到消息,他们就可以开始捕获过程。zmq.COMPLETE
选项做什么?@BenyaminJafari Mea Culpa-代码输入得很匆忙,而且这个想法比我的输入技能快-正确的选项设置是zmq.IMMEDIATE
模块常量,这可以防止将消息有效负载放入L1/L2不完整连接的队列(ZeroMQ ZMTP/RFC文档清楚地说明了状态完全连接管理的丰富程度),从而合理地避免了步骤上的任何延迟,这些步骤没有意义,可能会使到达
import zmq; print( zmq.zmq_version() ) # INF:
aCtx = zmq.Context( 4 ) # request 4-I/O-threads
aPUB = aCtx.socket( zmq.PUB ) # PUB-instance
aPUB.setsockopt( zmq.LINGER, 0 ) # avoid deadlock on close
aPUB.setsockopt( zmq.SNDBUF, 3 * PayLoadSIZE ) # FullHD ~ 6 MB, 4K ~ ...
aPUB.setsockopt( zmq.SNDHWM, aNumOfPicsInQUEUE ) # 1, ~3? ~10?, !1000 ...
aPUB.setsockopt( zmq.IMMEDIATE, 1 ) # ignore L1/L2-incomplete(s)
aPUB.setsockopt( zmq.CONFLATE, 1 ) # do not re-send "old"
aPUB.bind( <transport-class>:<port#> ) # tcp:? udp-multicast?
#-----------------------------------------------------------------------------[RTO]
# may like to set aPayLOAD = gzip.compress( dill.dumps( capture ), compressionLEVEL )
# yields reduced sizes of the serialised <capture> data
# at costs of about ~30~60 [ms] on either side
# which may lower the network traffic and .SNDBUF-sizing issues
#----------------------------------------------------------------------
while <any reason>:
try:
aPUB.send( aPayLOAD, zmq.NOBLOCK )
except:
# handle as per errno ...
finally:
pass
#----------------------------------------------------------------------
aPUB.close()
aCtx.term()
import zmq; print( zmq.zmq_version() ) # INF:
aCtx = zmq.Context() # request 4-I/O-threads
aSUB = aCtx.socket( zmq.SUB ) # SUB-instance
aSUB.setsockopt( zmq.LINGER, 0 ) # avoid deadlock on close
aSUB.setsockopt( zmq.RCVBUF, 3 * PayLoadSIZE ) # FullHD ~ 6 MB, 4K ~ ...
aSUB.setsockopt( zmq.RCVHWM, aNumOfPicsInQUEUE ) # 1, ~3? ~10?, !1000 ...
aSUB.setsockopt( zmq.IMMEDIATE, 1 ) # ignore L1/L2-incomplete(s)
aSUB.setsockopt( zmq.CONFLATE, 1 ) # do not re-recv "old"
aSUB.setsockopt( zmq.SUBSCRIBE, "" ) # do subscribe to whatever comes
aSUB.connect( <transport-class>:<port#> ) # tcp:? udp-multicast?
#-----------------------------------------------------------------------------[RTO]
while <any reason>:
try:
if ( aSUB.poll( zmq.POLLIN, 0 ) == 0 ):
# nothing in the receiving Queue ready-to-.recv()
# sleep()
# do some system work etc
else:
aPayLOAD = aSUB.recv( zmq.NOBLOCK )
#--------------------------------------------------------
# decompress / deserialise the original object
# capture = dill.loads( gzip.decompress( aPayLOAD ) )
#--------------------------------------------------------
# PROCESS THE DATA :
# ...
except:
# handle as per errno ...
finally:
pass
#----------------------------------------------------------------------
aSUB.close()
aCtx.term()