18

更新:読みやすくするために、reactorがシャットダウンする前にコールバックを追加する方法は次のとおりです。

reactor.addSystemEventTrigger('before', 'shutdown', callable)

元の質問は次のとおりです。


クライアントがサーバーに接続されていて、イベントを待機しているリアクターのメインループで冷却されている場合、CTRL-Cを押すと、「反対側への接続がクリーンでない方法で失われました:接続が失われました。 「」KeyboardInterruptがいつ発生するかを知ることができるように設定して、適切なクリーンアップを実行し、クリーンに切断できるようにするにはどうすればよいですか?または、可能であれば、CTRL-Cを使用せずにシャットダウンするためのよりクリーンな方法を実装するにはどうすればよいですか?

4

2 に答える 2

31

本当に、本当に Cc を具体的にキャッチしたい場合は、Python アプリケーションの通常の方法でこれを行うことができます - を使用して、やりたいことをsignal.signal実行するためのハンドラーをインストールします。SIGINTハンドラーから Twisted API を呼び出す場合は、reactor.callFromThread他のほとんどすべての Twisted API がシグナル ハンドラーからの呼び出しに対して安全でないため、必ず使用してください。

ただし、シャットダウン時のクリーンアップ コードを挿入することに本当に関心がIService.stopServiceある場合は、代わりに (またはそれが実装されているメカニズム)を使用することをお勧めしますreactor.addSystemEventTrigger

を使用している場合twistd、使用IService.stopServiceは簡単です。Application少なくとも 1 つのサービスが関連付けられたオブジェクトが既に存在します。stopServiceシャットダウン作業を行うカスタム メソッドを使用して、別のものを追加できます。メソッドは を返すことができDeferredます。そうである場合、シャットダウン プロセスはそれが起動するまで一時停止されDeferredます。これにより、ネットワーク (またはその他の非同期) 操作がさらに必要な場合でも、接続を適切にクリーンアップできます。

を使用していない場合は、直接twistd使用する方がおそらく簡単です。呼び出されるのと同じ状況で呼び出されるシャットダウン前reactor.addSystemEventTriggerトリガーをインストールできます。このトリガー (任意の呼び出し可能なオブジェクト) は、シャットダウンを遅らせるためにa を返すこともできます。これは(シャットダウンが開始される前に、シャットダウンが発生するたびに既に登録されているように) への呼び出しで行われます。IService.stopServiceDeferredreactor.addSystemEventTrigger('before', 'shutdown', callable)

service.tacは、カスタム サービスの作成と使用の例を示しています。

wxacceptance.pyaddSystemEventTriggerは、シャットダウンを (任意の) 3 秒遅らせて使用する例を示しています。

これらのメカニズムはどちらも、リアクターが停止するたびに通知を送信します。これは、Cc キーストロークが原因である可能性があります。kill -INT ...または、誰かが を使用したためか、どこかreactor.stop()が呼び出されたためである可能性があります。それらはすべてリアクターのシャットダウンにつながり、リアクターのシャットダウンは常にシャットダウン イベント トリガーを処理します。

于 2010-08-10T22:29:59.900 に答える
2

あなたが書いたクライアントについて話しているのか、サーバーについて話しているのかわかりません。

とにかく、「CTRL-C」に問題はありません。

サーバーをアプリケーションとして作成している場合。からサブクラス化し、twisted.application.service.Serviceおよび を定義startServicestopServiceます。アクティブなプロトコル インスタンスのリストを維持します。stopServiceそれらを通過し、それらを優雅に閉じるために使用します。

クライアントを持っている場合は、 をサブクラス化することもできますが、Serviceを使用する方が簡単reactor.addSystemEventTrigger('before','shutdown',myCleanUpFunction)で、この関数で接続を適切に閉じることができます。

于 2010-08-10T22:28:07.667 に答える