在ZeroMQ中调用recv_pyobj()时如何添加主题过滤器?

时间:2015-10-15 22:13:04

标签: python zeromq pyzmq

ZeroMQ提供了很好的文档,说明如何使用主题过滤器设置pub-sub pattern,如the api docs中所述。 ZeroMQ还为convenience提供了方法socket.send_json()socket.send_pyobj()(以及recv对应方)。

在pub-sub示例中,主题过滤器(字符串)附加到消息的开头(也是一个字符串)。使用内置序列化时,有没有办法设置主题过滤器?如果我使用dict发送Classsend_pyobj(),则无法在其前面添加字符串。

1 个答案:

答案 0 :(得分:8)

首先要注意的是,ZeroMQ不提供send_json()send_pyobj()作为便利方法,这些方法由pyzmq绑定提供。因此,ZMQ对这些数据类型一无所知 - 基本上正在发生的是这些方法只是对引擎盖下的数据进行序列化和反序列化。

和你一样,我还没有看到使用这些方便方法的pub / sub的一个例子,它不仅仅订阅了''。但是,应该是可能的,如果有点黑客这样做。

尽可能see here in the sourcesend_pyobj()使用pickle来序列化数据。您可以使用该事实来查看序列化后的数据。您可以在dictClass添加额外元素,前提是您可以确定它在序列化字符串中首先,然后查看序列化并使用字符串的开头作为您的订阅主题。如果无法确定您的主题元素将首先出现,那么您将需要创建一个您可以更多控制的某种信封,并将其与您的数据一起发送并在收到它时将其取消引用。

Hacky,丑陋,最终可能是一个坏主意,even according to the writers of the pyzmq binding themselves - 相关引用(强调增加):

  为方便起见,我们提供了三种内置的序列化方法,帮助Python开发人员学习libzmq ......这些方法是为了方便而不是为了提高性能而设计的,所以想要强调性能的开发人员应该使用他们的自己的序列化发送/接收方法。

自己序列化数据并在第一帧中发送包含您主题的正确多帧消息可能要好得多。您可以找到此类here的示例。

// publisher
self.socket.send_multipart([b'status',pickle.dumps(msg2)])

// subscriber
socket.setsockopt(zmq.SUBSCRIBE, 'status')
[topic,msg] = socket.recv_multipart()
msg2 = pickle.loads(msg)
print msg2['game']