5.1.4 会話型サービスの通信
XATMIインタフェースの,会話型サービスの通信形態について説明します。
会話型サービスの通信ができるのは,通信プロトコルにTCP/IPを使っている場合だけです。通信プロトコルにOSI TPを使っている場合は,会話型サービスの通信はできません。
- 〈この項の構成〉
(1) 会話型サービスの通信手順
会話型サービスの通信形態では,関数を呼び出して,通信相手とコネクションを確立してから通信をします。サービスを要求する手順を次に示します。
(a) コネクションの確立
クライアントUAPは,サービス関数とのコネクションを確立します。コネクションを確立するときは,tpconnect()【TPCONNECT】を使います。tpconnect()でコネクションを確立したUAPプロセスをオリジネータ,相手のUAPプロセスをサブオーディネータといいます。
tpconnect()が正常リターンした場合には,確立したコネクションを識別する記述子が正の値で返されます。この記述子を通信する関数に設定して,通信します。
サービス関数でtpreturn()を呼び出して処理を終了すると,コネクションは切断されます。
(コネクションの制御権)
tpconnect()の引数flagsには,制御権の有無を示すTPSENDONLY,TPRECVONLYのどちらかを設定します。TPSENDONLYを設定することで,そのプロセスは制御権を得て,データの送信関数tpsend()を使えるようになります。逆に,TPRECVONLYを設定すると,通信相手のプロセスに制御権が渡って,tpconnect()を呼び出したプロセスはデータの受信関数tprecv()を使えるようになります。
(b) データの送信(tpsend())
データを送信するときは,tpsend()【TPSEND】を使います。tpsend()の引数には,tpconnect()でリターンされた記述子を設定して,使うコネクションを特定します。
コネクションの制御権がない場合には,tpsend()は使えません。この場合,tpsend()はエラーリターンします。
コネクションの制御権を通信相手のプロセスに渡したい場合は,tpsend()のflagsにTPRECVONLYを設定します。このフラグを設定してtpsend()を呼び出すことで,通信相手のプロセスに制御権を渡すことになります。
サブオーディネータからtpsend()でデータを送信する場合は,受信したTPSVCINFO構造体から得た記述子を使ってください。
(c) データの受信(tprecv())
データを受信するときは,tprecv()【TPRECV】を使います。データは,非同期に受信します。tprecv()は,コネクションの制御権を持たないプロセスからだけ呼び出せます。
(監視時間について)
フラグにTPNOBLOCKを設定していない場合,tprecv()はデータを受信するまで待ちます。最大応答待ち時間は,OpenTP1の定義で指定します。定義については,マニュアル「OpenTP1 システム定義」を参照してください。
tprecv()を呼び出したプロセスがトランザクション下にある場合,最大応答待ち時間は,OpenTP1のシステム定義trn_expiration_timeオペランドで指定した値となります。この場合,最大応答待ち時間を過ぎると,そのプロセスは異常終了します(tprecv()はエラーリターンしません)。
tprecv()を呼び出したプロセスがトランザクション下にない場合,最大応答待ち時間は,OpenTP1のシステム定義watch_timeオペランドで指定した値となります。この場合,最大応答待ち時間を過ぎると,tprecv()はエラーリターンします。
(2) 会話型サービス通信の時間監視
会話型サービスの通信では,時間監視はすべてOpenTP1の定義に指定した値に従います。定義については,マニュアル「OpenTP1 システム定義」を参照してください。
タイムアウトには,トランザクション処理がタイムアウトになったことを示すトランザクションタイムアウトと,ブロッキング状態の待ちによるタイムアウトによるブロッキングタイムアウトがあります。トランザクションタイムアウトが起こった場合,そのプロセスは異常終了します。
設定したタイムアウト値を超えて,処理を待つ場合もあります(該当のデータでない応答が返ってきても,OpenTP1の監視タイマはリセットされるため)。また,フラグにTPNOTIMEを設定した場合は,タイムアウト値を無限大とします。ただし,トランザクションタイムアウトはこのフラグの有無に関係なく起こります。
(3) 会話型サービスの通信とトランザクションの関係
OpenTP1で使えるトランザクション管理の関数(dc_trn_〜,またはtx_〜)でトランザクションを制御します。OpenTP1でトランザクションを決着するかどうか,またはrollback_only状態かどうかは,サービス関数の処理結果,またはトランザクションを制御する関数によって決定されます。ただし,会話型サービスでは,次に示すエラーが起こると,該当のトランザクションブランチをrollback_only状態とします。
-
トランザクションタイムアウトが発生(異常終了します)。
-
型付きバッファ受信のエラー(受信した型が,許可されていない)。
-
TPESYSTEMエラーの発生(ただし,TPESYSTEMがリターンしてもrollback_only状態とならない場合もあります)。
-
tpdiscon()を実行。
-
tpsend()でエラーコードTPEEVENT(イベントコードがTPEV_SVCERR,TPEV_SVCFAIL)。
-
tprecv()でエラーコードTPEEVENT(イベントコードがTPEV_DISCONIMM,TPEV_SVCERR,TPEV_SVCFAIL)。
呼び出し側がトランザクション下にある場合,呼び出すサービスをトランザクションとして処理するかどうかは,関数tpconnect()の引数flagsに設定したパラメタで決まります。呼び出すサービスをトランザクションとしない場合に限り,TPNOTRANを設定してください。TPNOTRANを設定しても,トランザクションタイムアウトは起こります。
(4) ブロッキング状態が起こった場合の処置
会話型サービスの通信関数には,ブロッキング状態の場合の処置を示すTPNOBLOCKフラグがあります。このフラグを設定したtprecv()は,ブロッキング状態を検知した時点でエラーリターンします。このフラグを設定しないと,ブロッキング状態が解決するまで待つか,またはタイムアウトとなります(ただし,TPNOTIMEを設定していれば,ブロッキング状態が原因でのタイムアウトとはなりません)。OpenTP1では,このフラグが有効になるのは,tprecv()だけです。tpconnect(),tpsend()でこのフラグを設定しても無効となります。