1

私はツイストを学び始めたばかりで、Tcp4endpoint-classを使用して小さなtcpサーバー/クライアントを作成しました。1つを除いて、すべてが正常に機能します。

使用できないポートがリッスンポートとしてサーバーに与えられたというイベントを検出するために、endpoint-defererにerrbackを追加しました。このエラーバックがトリガーされますが、アプリケーションをエラーバックから終了できません。Reactor.stopは、reactorが実行されていないことを示す別のエラーを引き起こしますが、たとえばsys.exitは別のエラーをトリガーします。後者の2つの出力は、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で失敗する理由ReactorNotRunningは、listen呼び出す前に Deferred が失敗するためですreactor.run。つまり、あなたが実行した時点ですでに失敗しているd.addErrback(listenFailedため)、listenFailedすぐに呼び出されました。

これにはいくつかの解決策があります。1 つは、.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 に答える