【问题标题】:Exiting Twisted-application after listenFailure在 listenFailure 后退出 Twisted-application
【发布时间】:2012-08-18 04:35:02
【问题描述】:

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

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

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

【问题讨论】:

    标签: python twisted


    【解决方案1】:

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

    【讨论】:

    • 感谢您的精彩回答!
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多