2012-08-17 51 views
1

我刚刚开始学习扭曲并使用Tcp4endpoint-class编写了一个小型tcp服务器/客户端。一切工作正常,除了一件事。listenFailure后退出扭曲应用程序

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

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

回答

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.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() 
+0

谢谢你的答案! – 2012-08-18 07:16:27