一个最小的例子可以帮助你的问题更清楚。然而,基于多年 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 与 ReactorNotRunning 失败的原因是 listen Deferred 在您调用 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()