在listenFailure之后退出Twisted-application

时间:2012-08-17 14:01:00

标签: python twisted

我刚刚开始学习twisted并使用Tcp4endpoint类编写了一个小型tcp服务器/客户端。一切都很好,除了一件事。

为了检测将不可用端口作为监听端口提供给服务器的事件,我向端点 - 仲裁器添加了一个错误回送。这个errback被触发,但是,我无法从errback退出应用程序。 Reactor.stop导致另一个失败,说反应堆没有运行,而例如sys.exit触发另一个错误。只有当我按ctrl + c和gc命中时才会看到后者的输出。

我的问题是,有没有办法在listenFailure发生后让应用程序退出(干净利落)?

1 个答案:

答案 0 :(得分:3)

最小的例子有助于使您的问题更加清晰。然而,基于扭曲多年的经验,我有一个有根据的猜测。我想你写了一个这样的程序:

from twisted.internet import endpoints, reactor, protocol

factory = protocol.Factory()
factory.protocol = protocol.Protocol
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000)
d = endpoint.listen(factory)
def listenFailed(reason):
    reactor.stop()
d.addErrback(listenFailed)

reactor.run()

你走在正确的轨道上。不幸的是,您有订购问题。 reactor.stopReactorNotRunning而失败的原因是,在您致电listen之前reactor.run延期失败''。也就是说,它在您d.addErrback(listenFailed)时已经失败,因此立即调用了listenFailed

有很多解决方案。一种是编写.tac文件并使用服务:

from twisted.internet import endpoints, reactor, protocol
from twisted.application.internet import StreamServerEndpointService
from twisted.application.service import Application

application = Application("Some Kind Of Server")

factory = protocol.Factory()
factory.protocol = protocol.Protocol
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000)

service = StreamServerEndpointService(endpoint, factory)
service.setServiceParent(application)

这是使用twistd运行的,例如twistd -y thisfile.tac

另一种选择是使用服务基于reactor.callWhenRunning

的低级功能
from twisted.internet import endpoints, reactor, protocol

factory = protocol.Factory()
factory.protocol = protocol.Protocol
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8000)

def listen():
    d = endpoint.listen(factory)
    def listenFailed(reason):
        reactor.stop()
    d.addErrback(listenFailed)

reactor.callWhenRunning(listen)
reactor.run()