来自库函数

时间:2016-07-01 20:26:31

标签: python twisted twisted.client

我正在尝试实现一个充当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”错误。

最好的方法是什么?我不是很担心从远端收到回复,但我应该知道它是否失败以及原因。

2 个答案:

答案 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。