PyZMQ 如何通过 ZeroMQ 发送 None 数据

PyZMQ how to send None data over ZeroMQ

我的 PubSub 网络中的第一个节点正在读取一个 .csv 文件,并将数据作为多部分消息逐行转发。发送完最后一行后,我想发送带有 None 的最后一条消息,以向网络的其余部分表明我们已完成。

例如消息信封:pub.send_multipart(['some_topic'.encode('ascii'), None])

但是,如果我尝试发送它,则会收到以下错误:

TypeError('Frame 1 (None) does not support the buffer interface.',)>
Traceback (most recent call last):
  File "/*path*/anaconda3/envs/zeromq/lib/python3.6/site-packages/zmq/sugar/socket.py", line 426, in send_multipart
    memoryview(msg)
TypeError: memoryview: a bytes-like object is required, not 'NoneType'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "pub_facs.py", line 165, in facs_pub
    await pub.send_multipart([sub_key.encode('ascii'), None, None, None, None])
  File "/*path*/anaconda3/envs/zeromq/lib/python3.6/site-packages/zmq/_future.py", line 445, in _handle_send
    result = send(msg, **kwargs)
  File "/*path*/anaconda3/envs/zeromq/lib/python3.6/site-packages/zmq/sugar/socket.py", line 433, in send_multipart
    i, rmsg,
TypeError: Frame 1 (None) does not support the buffer interface.

当然,我可以将其设置为['some_topic', -1],但是如果我想用另一种编程语言(例如C#)进行自动对象分配,将数据设置为null就可以了, 但 -1 不是,如果该变量未初始化为整数。

通过 ZeroMQ (PyZMQ) 发送空消息的最佳方式是什么?我能以某种方式发送一个空的消息框吗? ZeroMQ 指南谈到 zmq_msg_init() 在 C 中创建一个空消息,但我不知道如何在 Python 中做到这一点。

通过 ZeroMQ 发送空消息的最佳方式是什么?

你的问题是需要在所涉及的任何一方都有相同的SER/DES策略。

ZeroMQ 不是造成此类问题的罪魁祸首。

如果您选择的语言绑定 (PyZMQ) 不允许处理和发送 None 数据类型,您的下一步可以通过 import struct 作曲
struct.pack( aDateTypeSpecificMASK, aDataToSEND )/根据自己的bits/bytes-mapping策略解码data-typesstruct.unpack( aDateTypeSpecificMASK, aDataJustRECVd )(这可能听起来很费力,但乍一看,您仍然可以绝对控制任何个人 remote-end 客户端生态系统,这是最强大的选择,不是吗?)

ZeroMQ 将 "just carry" bits/bytes-mapped 有效负载,无需任何干预。就这么简单。

我找到了一种发送 "None" 消息的简单方法:b''(空字节字符串),例如Python >=3.5(异步):

# send None message
await pub.send_multipart([sub_key.encode('ascii'), b'', b''])

# receive None message
msg = await sub.recv_multipart()
if msg[1]:
    # do stuff with message
else:
    print("Message is empty")

使用 C#:

if (!subSocket.TryReceiveFrameString(out topic)) continue;
if (!subSocket.TryReceiveFrameString(out data1)) continue;
if (!subSocket.TryReceiveFrameString(out data2)) continue;

if (data1 != "")
{
    // Do message stuff
}

我没有用其他语言测试过,但我感觉会很容易。