我正在尝试实现一个充当Twisted客户端的函数。它是从我无法控制的代码调用的。我尝试了类似的东西(这取自pbsimpleclient.py示例代码):
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util
def remcall(**kw):
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
# kw here is what's passed in via remcall
d.addCallback(lambda object: object.callRemote("echo", kw))
d.addCallback(lambda echo: 'server echoed: '+repr(echo))
d.addErrback(lambda reason: 'error: '+str(reason.value))
d.addCallback(util.println)
d.addCallback(lambda _: reactor.stop())
reactor.run()
来电者会拨打电话:
remcall(hello=1, world=2)
remcall(hi=3, there=4)
但正如您可能已经猜到的那样,它会产生“twisted.internet.error.ReactorNotRestartable”错误。
最好的方法是什么?我不是很担心从远端收到回复,但我应该知道它是否失败以及原因。
答案 0 :(得分:1)
从reactor.run()
函数中删除remcall
并将其追加到最后。同时删除d.addCallback(lambda _: reactor.stop())
def remcall(**kw):
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
# kw here is what's passed in via remcall
d.addCallback(lambda object: object.callRemote("echo", kw))
d.addCallback(lambda echo: 'server echoed: '+repr(echo))
d.addErrback(lambda reason: 'error: '+str(reason.value))
d.addCallback(util.println)
remcall(hello=1, world=2)
remcall(hi=3, there=3)
reactor.run() # this should be the last thing to run
反应堆只能运行一次。正在执行reactor.stop()
函数,除非您的应用程序需要完全停止运行,否则它不应该执行。这就是您获得ReactorNotRestartable
例外的原因。
答案 1 :(得分:0)
答案是使用钩针。
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
## Add these two lines
from crochet import setup, wait_for
setup()
from twisted.spread import pb
from twisted.internet import reactor
from twisted.python import util
## Add a wait_for decorator
@wait_for(timeout=5.0)
def remcall(**kw):
factory = pb.PBClientFactory()
reactor.connectTCP("localhost", 8789, factory)
d = factory.getRootObject()
# kw here is what's passed in via remcall
d.addCallback(lambda object: object.callRemote("echo", kw))
d.addCallback(lambda echo: 'server echoed: '+repr(echo))
d.addErrback(lambda reason: 'error: '+str(reason.value))
d.addCallback(util.println)
## Get rid of the reactor calls, and return d
# d.addCallback(lambda _: reactor.stop())
# reactor.run()
return d
然后来电者只需拨打
remcall(hello=1, world=2)
remcall(hi=3, there=4)
和钩针的@wait_for处理在反应堆线程中运行remcall。