17.6 asynchat -- 非同期ソケット コマンド/レスポンス ハンドラ

asynchatを使うと、asyncoreを基盤とした非同期な サーバ・クライアントをより簡単に開発する事ができます。 asynchatでは、プロトコルの要素が任意の文字列で終了するか、ま たは可変長の文字列であるようなプロトコルを容易に制御できるようになってい ます。asynchatは、抽象クラスasync_chatを定義してお り、async_chatを継承してcollect_incoming_data()メソッド とfound_terminator()メソッドを実装すれば使うことができます。 async_chatasyncoreは同じ非同期ループを使用してお り、asyncore.dispatcherasynchat.async_chatも同じチャネ ルマップに登録する事ができます。通常、asyncore.dispatcherはサー バチャネルとして使用し、リクエストの受け付け時に asynchat.async_chatオブジェクトを生成します。

クラス async_chat( )
このクラスは、asyncore.dispatcherから継承した抽象クラスです。 使用する際にはasync_chatのサブクラスを作成し、 collect_incoming_data()found_terminator()を定義し なければなりません。asyncore.dispatcherのメソッドを使用する事 もできますが、メッセージ/レスポンス処理を中心に行う場合には使えないメ ソッドもあります。

asyncore.dispatcherと同様に、async_chatselect()呼出し後のソケットの状態からイベントを生成します。 ポーリングループ開始後、イベント処理フレームワークが自動的に async_chatのメソッドを呼び出しますので、プログラマが処理を記述 する必要はありません。

asyncore.dispatcherと違い、async_chatでは プロデューサの first-in-first-outキュー(fifo)を作成する事ができ ます。プロデューサはmore()メソッドを必ず持ち、このメソッドで チャネル上に送出するデータを返します。プロデューサが枯渇状態 (i.e. これ以上のデータを持たない状態)にある場合、 more()は空文字列を返します。この時、async_chatは枯渇 状態にあるプロデューサをfifoから除去し、次のプロデューサが存在すればそ のプロデューサを使用します。fifoにプロデューサが存在しない場合、 handle_write()は何もしません。リモート端点からの入力の終了や 重要な中断点を検出する場合は、set_terminator()に記述します。

async_chatのサブクラスでは、入力メソッド collect_incoming_data()found_terminator()を定義 し、チャネルが非同期に受信するデータを処理します。以下にメソッドの解説 を示します。

close_when_done( )
プロデューサfifoのトップにNoneをプッシュします。このプロデュー サがポップされると、チャネルがクローズします。

collect_incoming_data( data)
チャネルが受信した不定長のデータをdataに指定して呼び出されます。 このメソッドは必ずオーバライドする必要があり、デフォルトの実装では、 NotImplementedError 例外を送出します。

discard_buffers( )
非常用のメソッドで、全ての入出力バッファとプロデューサfifoを廃棄します。

found_terminator( )
入力データストリームが、set_terminatorで指定した終了条件と一 致した場合に呼び出されます。このメソッドは必ずオーバライドする必要があ り、デフォルトの実装では、NotImplementedError 例外を送出し ます。入力データを参照する必要がある場合でも引数としては与えられないた め、入力バッファをインスタンス属性として参照しなければなりません。

get_terminator( )
現在のチャネルの終了条件を返します。

handle_close( )
チャネル閉じた時に呼び出されます。デフォルトの実装では単にチャネルのソ ケットをクローズします。

handle_read( )
チャネルの非同期ループでreadイベントが発生した時に呼び出され、デフォル トの実装では、set_terminator()で設定された終了条件をチェック します。終了条件として、特定の文字列か受信文字数を指定する事ができま す。終了条件が満たされている場合、handle_readは終了条件が成立 するよりも前のデータを引数としてcollect_incoming_data()を呼び 出し、その後found_terminator()を呼び出します。

handle_write( )
アプリケーションがデータを出力する時に呼び出され、デフォルトの実装では initiate_send()を呼び出します。initiate_send()では refill_buffer()を呼び出し、チャネルのプロデューサfifoからデー タを取得します。

push( data)
dataを持つsimple_producer(後述)オブジェクトを生成し、チ ャネルのproducer_fifoにプッシュして転送します。データをチャネル に書き出すために必要なのはこれだけですが、データの暗号化やチャンク化な どを行う場合には独自のプロデューサを使用する事もできます。

push_with_producer( producer)
指定したプロデューサオブジェクトをチャネルのfifoに追加します。これより 前にpushされたプロデューサが全て枯渇した後、チャネルはこのプロデューサ からmore()メソッドでデータを取得し、リモート端点に送信しま す。

readable( )
select()ループでこのチャネルの読み込み可能チェックを行う場 合には、Trueを返します。

refill_buffer( )
fifoの先頭にあるプロデューサのmore()メソッドを呼び出し、出力 バッファを補充します。先頭のプロデューサが枯渇状態の場合にはfifoからポ ップされ、その次のプロデューサがアクティブになります。アクティブなプロ デューサがNoneになると、チャネルはクローズされます。

set_terminator( term)
チャネルで検出する終了条件を設定します。termは入力プロトコルデー タの処理方式によって以下の3つの型の何れかを指定します。

term 説明
string 入力ストリーム中でstringが検出された時、 found_terminator()を呼び出します。
integer 指定された文字数が読み込まれた時、 found_terminator()を呼び出します。
None 永久にデータを読み込みます。

終了条件が成立しても、その後に続くデータは、 found_terminator()の呼出し後に再びチャネルを読み込めば取得す る事ができます。

writable( )
Should return True as long as items remain on the producer fifo, or the channel is connected and the channel's output buffer is non-empty.

プロデューサfifoが空ではないか、チャネルが接続中で出力バッファが空でな い場合、Trueを返します。



Subsections
ご意見やご指摘をお寄せになりたい方は、 このドキュメントについて... をご覧ください。