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



我的设置生成了一个 Node.js 子项,该子项使用 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 子服务器上调用而不会出现异常:

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方法? 还是我忽略了其他技巧?

经过一些实验,Gevent文档中的一些示例给出了一个可行的解决方案。 我采用的解决方案是创建一个从服务器端填充的 gevent 队列,并在循环中从单独的 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(事实上,我每次访问它时都可以使用 global)。 当需要发送异步消息时,MyClass调用self.outbox.put(messages)

然后在下面创建 ZeroRPC 实例时,我生成了每个实例:

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.

执行上述操作解决了我作为概念验证的问题。

相关内容

  • 没有找到相关文章

最新更新