1

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

为了检测将不可用端口作为侦听端口提供给服务器的事件,我在端点延迟器中添加了一个 errback。触发了这个 errback,但是,我无法从 errback 退出应用程序。Reactor.stop 导致另一个失败,表明反应堆没有运行,而例如 sys.exit 触发另一个错误。后两者的输出仅在我执行 ctrl+c 和 gc 命中时才能看到。

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

4

1 回答 1

3

一个最小的示例将有助于使您的问题更清楚。然而,根据多年的 Twisted 经验,我有一个有根据的猜测。我想你写了一个这样的程序:

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失败的原因ReactorNotRunninglistenDeferred 在你调用之前失败了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()
于 2012-08-17T20:35:02.760 回答