我刚刚开始学习twisted并使用Tcp4endpoint类编写了一个小型tcp服务器/客户端。一切都很好,除了一件事。
为了检测将不可用端口作为监听端口提供给服务器的事件,我向端点 - 仲裁器添加了一个错误回送。这个errback被触发,但是,我无法从errback退出应用程序。 Reactor.stop导致另一个失败,说反应堆没有运行,而例如sys.exit触发另一个错误。只有当我按ctrl + c和gc命中时才会看到后者的输出。
我的问题是,有没有办法在listenFailure发生后让应用程序退出(干净利落)?
答案 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.stop
因ReactorNotRunning
而失败的原因是,在您致电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()