如何使用 ZeroMQ PUB/SUB 发送由 ndarray 和 None 组成的 Python 字典?
How to send a Python dictionary consisting of ndarray and None using ZeroMQ PUB/SUB?
我正在尝试使用 ZeroMQ 传递包含 3 个图像的 python 字典(存储为 ndarray
),以将其作为消费者传递给另一个程序并将数据解析回原始形式。遵循了三种方法,但都无法成功。
下面是最小复制代码示例:
import pickle
import zmq
# Adding ZMQ Context
def zmq_context():
# Creating ZMQ context starts
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.connect('tcp://localhost:5002')
return footage_socket
wagon_dtl, ctr1_dtl, ctr2_dtl = NdArrays of images
socket_ctx = zmq_context()
# Trying two different ways of formatting the image before creating the dict, the below approach works for all three ndarrays
# 1st way
wagon_dtl = image_np_save # image_np_save is the original image
# 2nd way (this I tried because an ndarray isn't JSON serializable)
encoded, buffer = cv2.imencode('.jpg', image_np_save)
wagon_dtl = base64.b64encode(buffer)
if cond == "fulfilled":
full_wgn_dict = {"wagon_dtl": wagon_dtl, "ctr1_dtl": ctr1_dtl, "ctr2_dtl": ctr2_dtl}
# 1st way
dict_as_b64text = base64.b64encode(full_wgn_dict)
socket_ctx.send(dict_as_b64text)
# 2nd way
myjson = json.dumps(full_wgn_dict)
socket_ctx.send(myjson)
# 3rd way
dict_as_text = pickle.dumps(full_wgn_dict).encode('base64', 'strict')
socket_ctx.send(dict_as_text)
如何解决?
我在处理此解决方案时遵循了这些 Q/As:1, 2, , 4, 5
Q : "How to send a Python dictionary consisting of ndarray
and None
using ZeroMQ PUB/SUB
?"
很简单,最好使用 ready-made .send_pyobj()
方法来做到这一点。
发送方,
PUB
应该调用 socket.send_pyobj( full_wgn_dict )
-方法,这基本上是全部这边.
接收方,
每个潜在的SUB
-s 应重用.recv_pyobj()
-方法。
然而所有 SUB
-s 还必须再做一步,主动订阅以接收任何消息。
有关 socket.setsockopt( zmq.SUBSCRIBE, "" )
的详细信息,请参阅 ZeroMQ 文档 API,或者不要犹豫,从许多示例中汲取经验 here。
一些额外的技巧(琐碎的 dict
-s 不需要)可能有助于 SER/DES 阶段的 pickle
阶段。然而,这些超出了这个问题的范围,并且可能会在受控环境中带来优势,但在开放的、不受控制的环境中会带来问题,在这些环境中,您满足所需先决条件的机会为零——在我的应用程序中,我更喜欢使用 import dill as pickle
具有更高的 pickle.dumps()
-SER/DES 对象处理鲁棒性以及更多进步,例如存储 full-session 快照。致谢@MikeMcKearns
请随意 re-read __doc__
字符串中所有 syntax-related 详细信息的文档:
>>> print zmq.Socket.send_pyobj.__doc__
Send a Python object as a message using pickle to serialize.
Parameters
----------
obj : Python object
The Python object to send.
flags : int
Any valid flags for :func:`Socket.send`.
protocol : int
The pickle protocol number to use. The default is pickle.DEFAULT_PROTOCOL
where defined, and pickle.HIGHEST_PROTOCOL elsewhere.
>>> print zmq.Socket.recv_pyobj.__doc__
Receive a Python object as a message using pickle to serialize.
Parameters
----------
flags : int
Any valid flags for :func:`Socket.recv`.
Returns
-------
obj : Python object
The Python object that arrives as a message.
Raises
------
ZMQError
for any of the reasons :func:`~Socket.recv` might fail
我正在尝试使用 ZeroMQ 传递包含 3 个图像的 python 字典(存储为 ndarray
),以将其作为消费者传递给另一个程序并将数据解析回原始形式。遵循了三种方法,但都无法成功。
下面是最小复制代码示例:
import pickle
import zmq
# Adding ZMQ Context
def zmq_context():
# Creating ZMQ context starts
context = zmq.Context()
footage_socket = context.socket(zmq.PUB)
footage_socket.connect('tcp://localhost:5002')
return footage_socket
wagon_dtl, ctr1_dtl, ctr2_dtl = NdArrays of images
socket_ctx = zmq_context()
# Trying two different ways of formatting the image before creating the dict, the below approach works for all three ndarrays
# 1st way
wagon_dtl = image_np_save # image_np_save is the original image
# 2nd way (this I tried because an ndarray isn't JSON serializable)
encoded, buffer = cv2.imencode('.jpg', image_np_save)
wagon_dtl = base64.b64encode(buffer)
if cond == "fulfilled":
full_wgn_dict = {"wagon_dtl": wagon_dtl, "ctr1_dtl": ctr1_dtl, "ctr2_dtl": ctr2_dtl}
# 1st way
dict_as_b64text = base64.b64encode(full_wgn_dict)
socket_ctx.send(dict_as_b64text)
# 2nd way
myjson = json.dumps(full_wgn_dict)
socket_ctx.send(myjson)
# 3rd way
dict_as_text = pickle.dumps(full_wgn_dict).encode('base64', 'strict')
socket_ctx.send(dict_as_text)
如何解决?
我在处理此解决方案时遵循了这些 Q/As:1, 2,
Q : "How to send a Python dictionary consisting of
ndarray
andNone
using ZeroMQPUB/SUB
?"
很简单,最好使用 ready-made .send_pyobj()
方法来做到这一点。
发送方,PUB
应该调用 socket.send_pyobj( full_wgn_dict )
-方法,这基本上是全部这边.
接收方,
每个潜在的SUB
-s 应重用.recv_pyobj()
-方法。
然而所有 SUB
-s 还必须再做一步,主动订阅以接收任何消息。
有关 socket.setsockopt( zmq.SUBSCRIBE, "" )
的详细信息,请参阅 ZeroMQ 文档 API,或者不要犹豫,从许多示例中汲取经验 here。
一些额外的技巧(琐碎的 dict
-s 不需要)可能有助于 SER/DES 阶段的 pickle
阶段。然而,这些超出了这个问题的范围,并且可能会在受控环境中带来优势,但在开放的、不受控制的环境中会带来问题,在这些环境中,您满足所需先决条件的机会为零——在我的应用程序中,我更喜欢使用 import dill as pickle
具有更高的 pickle.dumps()
-SER/DES 对象处理鲁棒性以及更多进步,例如存储 full-session 快照。致谢@MikeMcKearns
请随意 re-read __doc__
字符串中所有 syntax-related 详细信息的文档:
>>> print zmq.Socket.send_pyobj.__doc__
Send a Python object as a message using pickle to serialize.
Parameters
----------
obj : Python object
The Python object to send.
flags : int
Any valid flags for :func:`Socket.send`.
protocol : int
The pickle protocol number to use. The default is pickle.DEFAULT_PROTOCOL
where defined, and pickle.HIGHEST_PROTOCOL elsewhere.
>>> print zmq.Socket.recv_pyobj.__doc__
Receive a Python object as a message using pickle to serialize.
Parameters
----------
flags : int
Any valid flags for :func:`Socket.recv`.
Returns
-------
obj : Python object
The Python object that arrives as a message.
Raises
------
ZMQError
for any of the reasons :func:`~Socket.recv` might fail