【问题标题】:How to send a Python dictionary consisting of ndarray and None using ZeroMQ PUB/SUB?如何使用 ZeroMQ PUB/SUB 发送由 ndarray 和 None 组成的 Python 字典?
【发布时间】:2021-01-27 20:09:26
【问题描述】:

我正在尝试使用 ZeroMQ 传递包含 3 个图像(存储为 ndarray)的 python 字典,以将其作为消费者传递给另一个程序,并将数据解析回原始形式。遵循了三种方式,但在任何一种方式中都无法取得成功。

以下是最小复制代码示例:

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/A:12345

【问题讨论】:

    标签: python json base64 zeromq encode


    【解决方案1】:

    Q“如何使用 ZeroMQ PUB/SUB 发送包含 ndarrayNone 的 Python 字典?”

    简单,最好使用现成的.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 对对象的处理具有更高的鲁棒性以及更多的进步,例如存储全会话快照。致谢@MikeMcKearns

    请随时重新阅读文档,了解__doc__ 字符串中所有与语法相关的详细信息:

    >>> 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
    

    【讨论】:

    • 太棒了!它就像一个魅力,中间没有任何额外的 SER/DER 步骤,并且延迟最小(对于 ~15 MB 数据,
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 2013-06-20
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多