Python客户端调用中的双向ZeroRPC导致AssertionError

我的安装程序有一个Node.js子代,它创build了一个Python对象的2路ZeroRPC会话对。

python方面是这样的:

class MyClass: def __init__(self, socketpath): self.client = zerorpc.Client() self.client.connect(socketpath) def sendtoclient(self, msg): self.client.receiveMessage(msg) if __name__ == '__main__': zpc = zerorpc.Server(MyClass(sys.argv[1])) zpc.bind(sys.argv[1] + "_python") zpc.run() 

Node.js子客户端可以调用Python服务器上的方法,但该服务器中的客户端不能在Node.js子服务器上调用,而不会收到exception:

 Traceback (most recent call last): File "/usr/lib64/python2.6/site-packages/gevent/queue.py", line 271, in _unlock getter.switch(getter) File "/usr/lib64/python2.6/site-packages/gevent/hub.py", line 534, in switch assert getcurrent() is self.hub, "Can only use Waiter.switch method from the Hub greenlet" AssertionError: Can only use Waiter.switch method from the Hub greenlet <callback at 0x3055e90 args=()> failed with AssertionError 

Python类中的客户端是否需要生成gevent,然后在需要时调用receiveMessage方法? 还是有一些其他的技巧我忽略了?

经过一些实验,一个可行的解决scheme来自Gevent的文档中的一些例子。 我使用的解决scheme是创build一个从服务器端填充的gevent Queue,并从一个单独的Greenlet循环输出。 所以在与我的服务器的文件,我补充说:

 import gevent from gevent.queue import Queue, Empty messagesOut = Queue() def clientWorker(address): client = zerorpc.Client() if (None != client): client.connect(address) while True: try: messages = messagesOut.get() client.passMessages(messages) # a method on the Node.js-side ZeroRPC server except: # Empty could be thrown here if you're interested pass finally: gevent.sleep(0) 

MyClass ,它的初始化更改为保留对self.outbox的队列引用(事实上,我可以在每次访问它时使用全局)。 当需要发送asynchronous消息时, MyClass调用self.outbox.put(messages)

然后在创buildZeroRPC实例的时候下面,我产生了每一个:

 if __name__ == '__main__': ge_client = gevent.spawn(clientWorker, sys.argv[1] + "_node2python") zpc = zerorpc.Server(messagesOut) zpc.bind(sys.argv[1] + "_python2node") ge_server = gevent.spawn(zpc.run) gevent.joinall([ge_client, ge_server]) # up and running here. 

做上述解决我的问题作为一个概念certificate。

Interesting Posts