我们在ZeroMQ中使用PUSH/PULL
可扩展的形式通信模式。发件人应用程序总共发送30,000条消息,每条消息10kB。有很多数据丢失,因此我们在发件人方面设置了以下内容:
zmq_socket = context.socket(zmq.PUSH)
zmq_socket.setsockopt(zmq.SNDBUF, 10240)
zmq_socket.setsockopt(zmq.SNDHWM, 1)
zmq_socket.bind("tcp://127.0.0.1:4999")
在接收方:
zmq_socket = context.socket(zmq.PULL)
zmqSocket.setReceiveBufferSize(10240);
zmqSocket.setRcvHWM(1);
zmq_socket.connect("tcp://127.0.0.1:4999")
仍有数据丢失。不确定我们如何避免数据包被静默删除。
编辑1:
Python中的发件人代码:
context = zmq.Context()
zmq_socket = context.socket(zmq.PUSH)
zmq_socket.setsockopt(zmq.SNDBUF, 10240)
zmq_socket.setsockopt(zmq.SNDHWM, 1)
zmq_socket.bind("tcp://127.0.0.1:4999")
for file_name in list_of_files: # Reads data from a list of files:
while True: # data from a file_name
with open(os.path.join(self.local_base_dir,file_name), 'r') as sf:
socket_data = sf.read(5120)
if socket_data == '':
sf.close()
break # until EoF
ret = zmq_socket.send(socket_data)
if ret == 0:
return True
if ret == -1:
print zmq_errno()
Java中的Receiver 代码:
private ZMQ.Socket zmqSocket = zmqContext.socket(ZMQ.PULL);
zmqSocket.setReceiveBufferSize(10240);
zmqSocket.setRcvHWM(1);
zmqSocket.connect(socketEndpoint);
String message = new String(zmqSocket.recv());
messages.add(message);
答案 0 :(得分:0)
使用ZMQ_IMMEDIATE
标志可以防止排队到没有完成连接的管道的消息丢失。
来自http://api.zeromq.org/4-2:zmq-setsockopt#toc21
ZMQ_IMMEDIATE
:仅将消息排入已完成的连接默认情况下,队列将填充传出连接,即使是 连接尚未完成。这可能会导致“丢失”的消息 带有循环路由的套接字(
REQ
,PUSH
,DEALER
)。如果这个选项 如果设置为1,则消息应仅排队到已完成的连接。 如果没有其他连接,这将导致套接字阻塞, 但会阻止队列填充等待连接的管道。 选项值类型int选项值unit boolean默认值0
(false
)适用的套接字类型全部,仅用于面向连接 传输。
zmq_socket.setsockopt(zmq.ZMQ_IMMEDIATE, 1)