bea ホーム | 製品 | dev2dev | support | askBEA
BEA Logo Tuxedo
 ドキュメントのダウンロード   サイトマップ   用語集 
検索
0

C 言語を使用した Tuxedo アプリケーションのプログラミング

 Previous Next Contents View as PDF  

イベント・ベースのクライアントおよびサーバのコーディング

ここでは、次の内容について説明します。

 


イベントの概要

イベント・ベースの通信では、特定の状況 (イベント) が発生すると、BEA Tuxedo システムのプロセスに通知されます。

BEA Tuxedo システムには、次の 2 種類のイベント・ベースの通信があります。

任意通知型イベント

任意通知型イベントは、メッセージを待たないクライアント・プログラム、またはメッセージを要求しないクライアント・プログラムとの通信に使用されるメッセージです。

ブローカ・イベント

ブローカ・イベントを使用すると、メッセージの受信と配信を行う「無名」ブローカを介して、クライアントとサーバが透過的に通信できるようになります。このブローカを使用した通信は、BEA Tuxedo システムの基本要素であるクライアント/サーバ通信パラダイムの 1 つです。

イベント・ブローカは、イベント・ポスト・メッセージを受信してフィルタ処理し、それらのメッセージをサブスクライバに配布する BEA Tuxedo のサブシステムです。ポスト元とは、特定のイベントが発生したときにそれをイベント・ブローカに報告 (ポスト) する BEA Tuxedo システムのプロセスです。サブスクライバとは、特定のイベントがポストされたときに常に通知する必要がある BEA Tuxedo システムのプロセスです。

BEA Tuxedo システムでは、サービスの要求側と提供側の数の比率が一定である必要はなく、任意の数のポスト元が任意の数のサブスクライバに対してメッセージ・バッファをポストできます。ポスト元は単にイベントをポストするだけで、情報を受信するプロセスや、情報の処理方法については関知しません。サブスクライバには指定されたイベントが通知されますが、その情報のポスト元は通知されません。このように、イベント・ブローカでは位置透過性が実現されます。

通常、イベント・ブローカ・アプリケーションは、例外イベントを処理します。アプリケーションの設計者は、アプリケーション内でどのイベントを例外イベントとして定義して監視する必要があるのかを決定しなければなりません。たとえば、銀行業務アプリケーションでは、高額な引き出しがあったときにイベントがポストされるように設定し、すべての引き出しに対してイベントがポストされる必要はありません。また、すべてのユーザがそのイベントをサブスクライブする必要はありません。支店長だけに通知すれば十分です。

通知処理

イベントがポストされると、イベント・ブローカはイベントをサブスクライブしているクライアントまたはサーバに対して、1 つ以上の通知処理を行います。次の表は、イベント・ブローカが行う通知処理の種類を示しています。

表 8-1 イベント・ブローカの通知処理

通知処理

説明

任意通知型通知メッセージ

クライアントは、tpnotify() で送信された場合と同じように、クライアントの任意通知型メッセージ処理ルーチンでイベント通知メッセージを受信します。

サービス呼び出し

サーバは、tpacall() によって送信された場合と同じように、サービス・ルーチンに対する入力としてイベント通知メッセージを受け取ります。

信頼性の高いキュー

イベント通知メッセージは、tpenqueue(3c) 関数を使用して、BEA Tuxedo システムの信頼性の高いキューに格納されます。イベント通知バッファは、バッファ内容が要求されるまで格納されます。BEA Tuxedo システムのクライアントまたはサーバ・プロセスで tpdequeue(3c) 関数を呼び出して、この通知バッファを取り出すことができます。または、TMQFORWARD(5) を設定して、通知バッファを取り出す BEA Tuxedo システムのサービス・ルーチンを自動的にディスパッチすることもできます。

/Q の詳細については、『BEA Tuxedo /Q コンポーネント』を参照してください。

アプリケーション管理者は、BEA Tuxedo の管理用 API を使用して、次の通知処理を行う EVENT_MIB(5) に関する追加情報 エントリを作成できます。

注記 EVENT_MIB(5) に関する追加情報 エントリを作成できるのは、BEA Tuxedo アプリケーション管理者だけです。

EVENT_MIB(5) に関する追加情報 の詳細については、『BEA Tuxedo のファイル形式とデータ記述方法』を参照してください。

イベント・ブローカ・サーバ

TMUSREVT は BEA Tuxedo システムで提供されるサーバで、ユーザ定義のイベントに対するイベント・ブローカとして動作します。TMUSREVT はイベント・レポート用のメッセージ・バッファを処理し、それらのバッファをフィルタ処理して配信します。イベントのブローカ処理を行うには、BEA Tuxedo アプリケーション管理者がこれらのサーバを 1 つ以上起動する必要があります。

TMSYSEVT は BEA Tuxedo システムで提供されるサーバで、システム定義のイベントに対するイベント・ブローカとして動作します。TMSYSEVTTMUSREVT は似ています。ただし、別個のサーバが提供されているので、アプリケーション管理者はこの 2 種類のイベント通知に対して異なる処理方法を取り入れることができます。詳細については、『BEA Tuxedo アプリケーションの設定』を参照してください。

システム定義のイベント

BEA Tuxedo システムでは、システムの警告と障害に関連する定義済みの特定のイベントが検出されてポストされます。これらの処理はイベント・ブローカによって行われます。たとえば、システム定義のイベントには、設定の変更、状態の変更、接続の障害、マシンの分断などがあります。イベント・ブローカによって検出されるシステム定義のイベントの全リストについては、『BEA Tuxedo のファイル形式とデータ記述方法』の EVENTS(5) を参照してください。

システム定義のイベントは、BEA Tuxedo システムで定義されているので、ポストする必要はありません。システム定義のイベント名は、アプリケーション定義のイベント名とは異なり、必ずドット (“.”) で始まります。アプリケーション定義のイベント名はドットで始めることはできません。

クライアントとサーバは、システム定義のイベントをサブスクライブできます。ただし、システム定義のイベントは、アプリケーション内のすべてのクライアントが使用するのではなく、主にアプリケーション管理者が使用します。

イベント・ブローカをアプリケーションに組み込む場合、イベント・ブローカが多数のサブスクライバに大量の配信を行うためのシステムではないことを考慮してください。発生するすべての動作に対してイベントをポストしないでください。また、すべてのクライアントとサーバがイベントをサブスクライブする必要はありません。イベント・ブローカに負荷がかかると、システムのパフォーマンスに影響し、通知が行われなくなる場合があります。負荷を最小限にするには、『Tuxedo システムのインストール』で説明するように、アプリケーション管理者がオペレーティング・システムの IPC 資源を慎重に調整する必要があります。

イベント・ブローカ・プログラミング・インターフェイス

イベント・ブローカ・プログラミング・インターフェイスは、ワークステーションを含むすべての BEA Tuxedo システムのサーバ・プロセスおよびクライアント・プロセスに対して C 言語および COBOL 言語で使用できます。

プログラマは、次の処理をコーディングします。

  1. クライアントまたはサーバは、アプリケーション定義のイベント名にバッファをポストします。

  2. ポストされたバッファは、そのイベントをサブスクライブしている任意の数のプロセスに転送されます。

サブスクライバへの通知方法にはいろいろな方法 (「通知処理」を参照) があり、イベントはフィルタ処理されます。通知処理とフィルタ処理は、プログラミング・インターフェイスと BEA Tuxedo システムの管理用 API を使用して設定します。

 


任意通知型メッセージ・ハンドラの定義

任意通知型メッセージ・ハンドラ関数を定義するには、次の文法を使用して tpsetunsol(3c) 関数を呼び出します。

int
tpsetunsol(*myfunc)

tpsetunsol() 関数の引数は、次の表で説明する myfunc だけです。

表 8-2 tpsetunsol( ) 関数の引数

引数

説明

myfunc

コールバック関数のプロトタイプに準拠する関数へのポインタ。このプロトタイプに準拠するには、関数で次の 3 つのパラメータを使用できることが必要です。

クライアントが任意通知型メッセージを受信すると、そのメッセージと共にコールバック関数がディスパッチされます。できる限りタスクが中断されないようにするには、任意通知型メッセージのハンドラ関数で最小限の処理しか行われないようにコーディングします。このようにすると、ハンドラ関数が待機中のプロセスにすぐに戻ることができます。

 


任意通知型メッセージの送信

BEA Tuxedo システムでは、要求/応答型呼び出しまたは会話型通信の処理を妨げずに、クライアント・プロセスに任意通知型メッセージを送信できます。

任意通知型メッセージは、名前、または以前に処理されたメッセージと共に受信した識別子を使用して、クライアント・プロセスに送信できます。名前による送信には tpbroadcast(3c)、識別子による送信には tpnotify(3c) を使用します。tpbroadcast() で送信されるメッセージの発信元は、サービスまたは別のクライアントです。tpnotify() で送信されるメッセージの発信元は、サービスだけです。


 

名前によるメッセージのブロードキャスト

tpbroadcast(3c) を使用すると、アプリケーションの登録されたクライアントにメッセージが送信されます。tpbroadcast() は、サービスまたは別のクライアントから呼び出すことができます。登録されたクライアントとは、tpinit() を呼び出したが、まだ tpterm() を呼び出してはいないクライアントのことです。

tpbroadcast() 関数の呼び出しには、次の文法を使用します。

int
tpbroadcast(char *lmid, char *usrname, char *cltname, char *data, long len, long flags)

次の表は、tpbroadcast() 関数の引数を示しています。

表 8-3 tpbroadcast( ) 関数の引数

引数

説明

lmid

クライアントの論理マシン識別子を指すポインタ。NULL 値をワイルドカードとして使用できるので、複数のクライアントにメッセージを送信できます。

usrname

クライアント・プロセスのユーザ名が存在する場合、そのユーザ名を指すポインタ。NULL 値をワイルドカードとして使用できるので、複数のクライアントにメッセージを送信できます。

cltname

クライアント・プロセスのクライアント名が存在する場合、そのクライアント名を指すポインタ。NULL 値をワイルドカードとして使用できるので、複数のクライアントにメッセージを送信できます。

data

メッセージの内容を指すポインタ。

len

メッセージ・バッファのサイズ。data が自己記述型のバッファ・タイプ (FML など) を指す場合、len に 0 を設定できます。

flags

フラグのオプション。使用できるフラグについては、『BEA Tuxedo C リファレンス』の tpbroadcast(3c) を参照してください。

次のコード例は、すべてのクライアントを送信先として tpbroadcast() を呼び出す方法を示しています。送信メッセージは、STRING 型バッファ内にあります。

コード リスト 8-1 tpbroadcast( ) の使用

char *strbuf;

if ((strbuf = tpalloc("STRING", NULL, 0)) == NULL) {
error routine
}

(void) strcpy(strbuf, "hello, world");

if (tpbroadcast(NULL, NULL, NULL, strbuf, 0, TPSIGRSTRT) == -1)
error routine

識別子によるメッセージのブロードキャスト

tpnotify(3c) 関数を使用すると、以前に処理されたメッセージと共に受信した識別子を使用してメッセージがブロードキャストされます。tpnotify() 関数は、サービスからのみ呼び出すことができます。

tpnotify() 関数の呼び出しには、次の文法を使用します。

int
tpnotify(CLIENTID *clientid, char *data, long len, long flags)

次の表は、tpnotify() 関数の引数を示しています。

表 8-4 tpnotify( ) 関数の引数

引数

説明

clientid

CLIENTID 構造体を指すポインタ。この構造体は、このサービスへの要求を持つ TPSVCINFO 構造体から取得されたものです。

data

メッセージの内容を指すポインタ。

len

メッセージ・バッファのサイズ。data が自己記述型のバッファ・タイプ (FML など) を指す場合、len に 0 を設定できます。

flags

フラグのオプション。使用できるフラグについては、『BEA Tuxedo C リファレンス』の tpnotify(3c) を参照してください。

 


任意通知型メッセージの確認

クライアントが「ディップ・イン」通知モードで実行されている場合に任意通知型メッセージがあるかどうかを確認するには、次の文法を使用して tpchkunsol(3c) 関数を呼び出します。

int
tpchkunsol()

この関数に引数はありません。

未処理のメッセージがある場合、tpsetunsol() で指定された任意通知型メッセージ処理関数が呼び出されます。処理が終了すると、この関数は処理した任意通知型メッセージの数、またはエラーを示す -1 を返します。

クライアントがシグナル・ベースまたはスレッド・ベースの通知モードで実行されている場合、またはクライアントが任意通知型メッセージを無視している場合にこの関数を呼び出すと、関数は何も処理を行わずにすぐに制御を戻します。

 


イベントのサブスクライブ

tpsubscribe(3c) 関数を使用すると、BEA Tuxedo システムのクライアントまたはサーバがイベントをサブスクライブできるようになります。

サブスクライバは、任意通知型通知メッセージ、サービス呼び出し、高い信頼性のキュー、またはアプリケーション管理者が設定する別の通知方法によって、通知を受け取ります。別の通知方法の設定については、『BEA Tuxedo アプリケーションの設定』を参照してください。

tpsubscribe() 関数の呼び出しには、次の文法を使用します。

long handle
tpsubscribe (char *eventexpr, char *filter, TPEVCTL *ctl, long flags)

次の表は、tpsubscribe() 関数の引数を示しています。

表 8-5 tpsubscribe( ) 関数の引数

引数

説明

eventexpr

プロセスがサブスクライブする 1 つ以上のイベントを指すポインタ。正規表現を含み、NULL 文字で終了する最大 255 文字の文字列を指定します。正規表現は、tpsubscribe(3c) で指定された形式です (『BEA Tuxedo C リファレンス』を参照)。たとえば、次のように eventexpr を設定します。

filter

ブール型のフィルタ規則を含む文字列を指すポインタ。イベント・ブローカがイベントをポストする前に、この規則を評価する必要があります。ポストするイベントを受け取ると、イベント・ブローカはそのイベントのデータにフィルタ規則 (存在する場合) を適用します。データが正しく評価された場合、イベント・ブローカは指定された通知方法を呼び出します。正しく評価されなかった場合、イベント・ブローカは指定された通知方法を無視します。呼び出し元は、異なるフィルタ・ルールを利用して同じイベントを何度でもサブスクライブすることができます。

イベント・フィルタ機能を使用すると、サブスクライバは通知されるイベントを限定できます。たとえば、100 万円を超える額の引き出しがあった場合に、イベントがポストされるとします。その場合、サブスクライバが 100 万円より高い額 (たとえば 500 万円) の通知だけを必要とすることがあります。または、特定の顧客による高額の引き出しの通知だけを必要とする場合があります。

フィルタ・ルールは、それが適用される型付きバッファに固有なものです。フィルタ規則の詳細については、『BEA Tuxedo C リファレンス』の tpsubscribe(3c) を参照してください。

ctl

サブスクライバへのイベント通知の方法を制御するフラグを指すポインタ。次の値を指定できます。

flags

フラグのオプション。使用できるフラグについては、『BEA Tuxedo C リファレンス』の tpsubscribe(3c) を参照してください。

システム定義のイベントとアプリケーション定義のイベントは、tpsubscribe() 関数を使用してサブスクライブできます。

サブスクリプション、および MIB を更新するために BEA Tuxedo システムのサーバ・プロセスで実行されるサービス・ルーチンは、信頼されたコードと見なされます。

任意通知型メッセージを使用した通知

サブスクライバが BEA Tuxedo システムのクライアント・プロセスであり、ctl に NULL が設定されている場合、クライアントがサブスクライブしているイベントがポストされると、イベント・ブローカは次のようにサブスクライバに任意通知型メッセージを送ります。eventexpr に対して正常に評価されたイベント名がポストされると、イベント・ブローカは対応付けられたフィルタ規則でポストされたデータを確認します。データがフィルタ規則で正しく評価された場合 (またはイベントにフィルタ規則がない場合)、サブスクライバはイベントと共にポストされたデータと任意通知型メッセージを受信します。

任意通知型メッセージを受け取るには、クライアントは tpsetunsol() 関数を使用して、任意通知型メッセージ処理ルーチンを登録しておく必要があります。

クライアントが任意通知型メッセージによってイベント通知を受け取った場合、終了する前にイベント・ブローカのアクティブなサブスクリプションのリストからそのサブスクリプションを削除する必要があります。サブスクリプションの削除には tpunsubscribe() 関数を使用します。

サービス呼び出しまたは信頼できるキューを使用した通知

サービス呼び出しを使用したイベント通知では、アプリケーションの特定の条件に対して自動的に応答するようにプログラミングできます。高い信頼性のキューを使用したイベント通知では、イベント・データが損失しないことが保証されます。また、サブスクライバがいつでもイベント・データを取り出せるという柔軟性があります。

サブスクライバ (クライアント・プロセスまたはサーバ・プロセス) がイベント通知をサービス・ルーチンまたは安定記憶領域のキューに送信する場合、tpsubscribe() の ctl パラメータが有効な TPEVCTL 構造体を指していることが必要です。

TPEVCTL 構造体には、次の情報が格納されています。

long   flags;
char name1[32];
char name2[32];
TPQCTL qctl;

次の表は、TPEVCTL 型バッファのデータ構造を示しています。

表 8-6 TPEVCTL 型バッファの形式

フィールド

説明

flags

フラグのオプション。フラグの詳細については、『BEA Tuxedo C リファレンス』の tpsubscribe(3c) を参照してください。

name1

32 文字以下の文字列。

name2

32 文字以下の文字列。

qctl

TPQCTL 構造体。詳細については、『BEA Tuxedo C リファレンス』の tpsubscribe(3c) を参照してください。

 


イベントに対するサブスクリプションの削除

tpunsubscribe(3c) 関数を使用すると、BEA Tuxedo システムのクライアントまたはサーバがイベントに対するサブスクリプションを削除できます。

tpunsubscribe() 関数の呼び出しには、次の文法を使用します。

int
tpunsubscribe (long subscription, long flags)

次の表は、tpunsubscribe() 関数の引数を示しています。

表 8-7 tpunsubscribe( ) 関数の引数

引数

説明

subscription

tpsubscribe() への呼び出しで返されるサブスクリプション・ハンドル。

flags

フラグのオプション。使用できるフラグについては、『BEA Tuxedo C リファレンス』の tpunsubscribe(3c) を参照してください。

 


イベントのポスト

tppost(3c) 関数を使用すると、BEA Tuxedo のクライアントまたはサーバがイベントをポストできます。

tppost() 関数の呼び出しには、次の文法を使用します。

tppost(char *eventname, char *data, long len, long flags)

次の表は、tppost() 関数の引数を示しています。

表 8-8 tppost( ) 関数の引数

引数

説明

eventname

31 文字以下の文字列と最後に NULL 文字を含むイベント名を指すポインタ。名前をドット (“.“)で始めることはできません。ドットは、BEA Tuxedo のシステム定義のイベントの先頭文字として予約されています。イベントのサブスクライブでは、イベント名にワイルド・カードを使用して、1 回の関数呼び出しで複数のイベントをサブスクライブすることができます。そのため関連するイベント名のカテゴリに同じ接頭語を使用すると便利です。

data

tpalloc() 関数で既に割り当てられているバッファを指すポインタ。

len

イベントと共にポストするデータ・バッファのサイズ。data が長さを指定する必要がないバッファ・タイプ (FML フィールド化バッファなど) を指している場合、または NULL が設定されている場合、len は無視され、データなしでイベントがポストされます。

flags

フラグのオプション。使用できるフラグについては、『BEA Tuxedo C リファレンス』の tppost(3c) を参照してください。

次のコード例は、BEA Tuxedo システムの銀行業務のサンプル・アプリケーション bankapp から引用したイベント・ポストを示しています。この例は、WITHDRAWAL サービスの一部です。WITHDRAWAL サービスは、10,000 ドルを超える引き出しかどうかを確認し、また BANK_TLR_WITHDRAWAL イベントをポストします。

コード リスト 8-2 tppost() を使用したイベントのポスト

.
.
.
/* 関連するイベント・ロジック */
static float evt_thresh = 10000.00 ; /* デフォルトのイベントしきい値 */
static char emsg[200] ; /* イベント・ポスト・ロジックで使用 */
.
.
.
/* BANK_TLR_WITHDRAWAL イベントをポストするかどうかの判定*/
if (amt < evt_thresh) {
/* ポストするイベントはありません。 */
tpreturn(TPSUCCESS, 0,transb->data , 0L, 0);
}
/* イベントをポストする準備 */
if ((Fchg (transf, EVENT_NAME, 0, "BANK_TLR_WITHDRAWAL", (FLDLEN)0) == -1) ||
(Fchg (transf, EVENT_TIME, 0, gettime(), (FLDLEN)0) == -1) ||
(Fchg (transf, AMOUNT, 0, (char *)&amt, (FLDLEN)0) == -1)) {
(void)sprintf (emsg, "Fchg failed for event fields:%s",
Fstrerror(Ferror)) ;
}
/* イベントのポスト */
else if (tppost ("BANK_TLR_WITHDRAWAL", /* イベント名 */
(char *)transf, /* データ */
0L, /* 長さ */
TPNOTRAN | TPSIGRSTRT) == -1) {
/* イベント・ブローカを使用できない場合、エラーを無視 */
if (tperrno != TPENOENT)
(void)sprintf (emsg, "tppost failed:%s", tpstrerror (tperrno));
}

このコード例では、アプリケーションで目立った状況が発生したことを示すために、イベントをイベント・ブローカにポストしているだけです。特定のイベントに関心を持つクライアント (必要に応じて処理を行うクライアント) のイベントへのサブスクリプションは、別にコーディングします。

 


イベントのサブスクリプションの例

次のコード例は、bankapp アプリケーション・サーバの一部であり、このサーバは BANK_TLR_.* イベントをサブスクライブしています。この例には、前述の例の BANK_TLR_WITHDRAWAL イベントと、BANK_TLR_ で始まるそのほかのイベント名が含まれています。合致するイベントがポストされると、WATCHDOG サービスへの呼び出しを使用して、アプリケーションからサブスクライバにイベントが通知されます。

コード リスト 8-3 tpsubscribe() を使用したイベントのサブスクライブ

.
.
.
/* イベント・サブスクリプション・ハンドル */
static long sub_ev_largeamt = 0L ;
.
.
.
/* 'w' (WATCHDOG のしきい値) にデフォルト値を設定 */
(void)strcpy (amt_expr, "AMOUNT > 10000.00") ;
.
.
.
/*
* 高額な引き出しが行われた場合に
* 生成されるイベントをサブスクライブ
*/
evctl.flags = TPEVSERVICE ;
(void)strcpy (evctl.name1, "WATCHDOG") ;
/* サブスクライブ */
sub_ev_largeamt = tpsubscribe ("BANK_TLR_.*",amt_expr,&evctl,TPSIGRSTRT) ;
if (sub_ev_largeamt == -1L) {
(void)userlog ("ERROR:tpsubscribe for event BANK_TLR_.* failed:%s",
tpstrerror(tperrno)) ;
return -1 ;
}
.
.
.
{
/* イベントへのサブスクリプションを削除 */
if (tpunsubscribe (sub_ev_largeamt, TPSIGRSTRT) == -1)
(void)userlog ("ERROR:tpunsubscribe to event BANK_TLR_.* failed:%s",
tpstrerror(tperrno)) ;
return ;
}
/*
* BANK_TLR_.* イベントがポストされたときに呼び出されるサービス
*/
void
#if defined(__STDC__) || defined(__cplusplus)
WATCHDOG(TPSVCINFO *transb)
#else
WATCHDOG(transb)
TPSVCINFO *transb;
#endif
{
FBFR *transf; /* 復号化されたメッセージのフィールド化バッファ */
/* TPSVCINFO データ・バッファを指すポインタを設定します。 */
transf = (FBFR *)transb->data;
/* ログ・エントリを標準出力に出力 */
(void)fprintf (stdout, "%20s|%28s|%8ld|%10.2f¥n",
Fvals (transf, EVENT_NAME, 0),
Fvals (transf, EVENT_TIME, 0),
Fvall (transf, ACCOUNT_ID, 0),
*( (float *)CFfind (transf, AMOUNT, 0, NULL, FLD_FLOAT)) );
/* イベントのサブスクライバのサービス・ルーチンから返されるデータはありません。 */
tpreturn(TPSUCCESS, 0,NULL, 0L, 0);
}

 

Back to Top Previous Next
Contact e-docsContact BEAwebmasterprivacy