3

ツイストで失われた接続を処理するために、次のコードを記述しました。

class Foo(LineReceiver):
    def connectionLost(self, reason):
        if reason.type != ConnectionLost:
            reactor.stop()
    def terminate(self):
        self.transport.loseConnection()

このterminateメソッドは、いくつかの入出力プロトコルによって呼び出されます。メソッドを呼び出す代わりにCtrl-Cでプログラムを中断すると、「実行中のreactorを停止できません」というエラーを回避するためにメソッドreason.typeをテストする必要がありました。connectionLostterminate

このコードは機能しますが、ツイストで接続の終わりを管理するよりエレガントな方法があるのだろうか?ありがとう !

4

1 に答える 1

4

あなたが直面している問題は、リアクターを停止する既にインストールされているシグナル ハンドラーをcontrol+が呼び出していることです。Cリアクターは、停止中にメソッドを呼び出します。connectionLostこれは、リアクターをシャットダウンすると、すべての接続が自動的に閉じられるためです。次に、プロトコルはリアクターを停止しようとしますが、既に停止されていることがわかります!

この状態を回避する簡単な (完全に正しいとは言えませんが) 方法は、running停止する前にリアクターのアトリビュートを確認することです。次のようにします。

def connectionLost(self, reason):
    if reactor.running:
        reactor.stop()

(おそらく、そのように例外タイプをチェックするべきではないFailure.checkことに注意してください。実際に理由のタイプを気にする場合は、代わりに使用することをお勧めしますが、ほとんどの場合、理由のタイプを気にする必要はありません。たとえば、切断によって SSL セッションが終了するかどうかなど、その切断の非常に具体的な属性を確認しようとしている場合を除き、切断された接続は単に切断された接続です。)

これをより徹底的にチェックしたい場合は、"before", "shutdown"システム イベント トリガーを介してリアクタの状態を監視するか、Twisted 12.3 で導入されたtwisted.internet.task.reactAPIを使用する必要があります。

于 2012-12-29T01:17:32.130 に答える