我第一次尝试(PY)ZMQ,并想知道是否可以使用PUB / SUB发送完整的FILE(二进制)?我需要向许多订阅者发送数据库更新。我看到短消息的例子,但不是文件。有可能吗?
的出版商: 的
import zmq
import time
import os
import sys
while True:
print 'loop'
msg = 'C:\TEMP\personnel.db'
# Prepare context & publisher
context = zmq.Context()
publisher = context.socket(zmq.PUB)
publisher.bind("tcp://*:2002")
time.sleep(1)
curFile = 'C:/TEMP/personnel.db'
size = os.stat(curFile).st_size
print 'File size:',size
target = open(curFile, 'rb')
file = target.read(size)
if file:
publisher.send(file)
publisher.close()
context.term()
target.close()
time.sleep(10)
的订户: 的
'''always listening'''
import zmq
import os
import time
import sys
while True:
path = 'C:/TEST'
filename = 'personnel.db'
destfile = path + '/' + filename
if os.path.isfile(destfile):
os.remove(destfile)
time.sleep(2)
context = zmq.Context()
subscriber = context.socket(zmq.SUB)
subscriber.connect("tcp://127.0.0.1:2002")
subscriber.setsockopt(zmq.SUBSCRIBE,'')
msg = subscriber.recv(313344)
if msg:
f = open(destfile, 'wb')
print 'open'
f.write(msg)
print 'close\n'
f.close()
time.sleep(5)
答案 0 :(得分:1)
您应该可以使用zmq和PUB / SUB模式将文件分发给许多订阅者。
您的代码几乎就在那里,换句话说,它可能在大多数情况下都可以使用,可以稍微改进一下。
消息在发布时(生活在PUB套接字中)必须适合内存,并保持在那里,直到最后一个当前订阅的消费者没有读出或断开连接。
收到消息时,消息也必须适合内存。但是对于合理的大文件(比如你的313 kB),它应该可以工作,除非你真的很短的RAM。
如果您有多个消费者,其中一个消费者的阅读速度比其他消费者慢得多,那么它将开始放慢所有消费者的速度。 Zmq正在解释这个问题,并提出了一些如何避免它的方法(例如,慢速用户的自杀)。
但是,在大多数情况下,您不会遇到此问题。
zmq消息传递非常快。没有问题,如果您尽早启动消费者,那么发布商zmq会使这种情况变得简单,消费者将自动连接。
但是,您的发布者应允许消费者在开始发布之前进行连接,您的代码在发送消息之前会进行1秒睡眠,这就足够了。
zmq提供了一个称为多部分消息的功能,但根据doc,它必须在发送之前完全适合(所有消息部分)在内存中,因此这不是使用的技巧。
另一方面,您可以通过这种方式创建“应用程序级多部分协议”,即您决定发送具有(hasNextPart,chunkData)结构的消息。通过这种方式,您可以发送控制良好的大小的消息,只有最后一个消息会告诉“hasNextPart”== False。
然后,消费者将读取并写入磁盘所有部分,直到最后一条消息,声称没有其他部分到达。