2012-08-17 118 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