7.4.1 XATMIインタフェースの例
(1) リクエスト/レスポンス型サービスの通信の例
(a) 処理の概要
ここで示す例題の処理概要を,次に説明します。
[説明]宿泊施設の空き状況を調べるサービスと,飛行機の空き状況を調べるサービスを,SUPから呼びます。前者は非同期に,後者は同期的に応答を受信します。
(b) UAPの構成
例題のUAPの構成を次の図に示します。
(c) 通信に使う型付きバッファ
通信に使う型付きバッファの構造体を次に示します。
struct hotel { struct plane { DCLONG date; DCLONG date; char place[128]; char dest[128]; char hname[128]; DCLONG departure; DCLONG status; DCLONG status; } }
(d) SUPの例
-
XATMIインタフェース定義の例
リクエスト/レスポンス型サービスの例題で示すSUPのXATMIインタフェース定義を次に示します。
10 /* SUPのXATMIインタフェース定義の例(rrsup.defファイル)*/ 20 called_servers = { "rrspp.def" };
-
SUPのコーディング例
リクエスト/レスポンス型サービスの例題で示すSUPのコーディング例を次に示します。
10 /* SUPの例(rrsup.cファイル)*/ 20 #include <stdio.h> 30 #include <stdlib.h> 40 #include <string.h> 50 #include <dcrpc.h> 60 #include <xatmi.h> 70 #include <dcadm.h> 80 /* 90 * XATMIスタブヘッダファイル 100 */ 110 #include "rrsup_stbx.h" 120 main() 130 { 140 /* 150 * 変数の定義 160 */ 170 struct hotel *hptr; 180 struct plane *pptr; 190 struct errmsg *werrmsg ; 200 long hlen, plen ; 210 int cd ; 220 int rc; 230 /* 240 * RPC-OPEN(UAPの開始) 250 */ 260 rc = dc_rpc_open(DCNOFLAGS); 270 if(rc != DC_OK){ 280 printf("dc_rpc_openに失敗しました。\ 290 ERROR CODE = %d \n", rc); 300 goto PROG_END; 310 } 320 /* 330 * ADM-COMPLETE(ユーザサーバの開始処理完了の報告) 340 */ 350 rc = dc_adm_complete(DCNOFLAGS); 360 if(rc != DC_OK){ 370 printf("dc_adm_completeに失敗しました。\ 380 ERROR CODE = %d \n", rc); 390 goto PROG_END; 400 } 410 /* 420 * TPALLOC(型付きバッファの確保) 430 */ 440 /* 宿泊施設空き状況検索サービス用 */ 450 hptr = (struct hotel *)tpalloc("X_COMMON", "hotel", 0); 460 if(hptr == NULL){ 470 printf("tpallocに失敗しました。\ 480 ERROR CODE = %d \n", tperrno); 490 goto PROG_END; 500 } 510 /* 飛行機空き状況検索サービス用 */ 520 pptr = (struct plane *)tpalloc("X_COMMON", "plane", 0); 530 if(pptr == NULL){ 540 printf("tpallocに失敗しました。\ 550 ERROR CODE = %d \n", tperrno); 560 goto PROG_END; 570 } 580 /* 590 * データの設定 600 */ 610 hptr->date = 940415 ; 620 strcpy(hptr->place, "SAPPORO") ; 630 strcpy(hptr->hname, "PRINCE") ; 640 hptr->status = 0 ; 650 pptr->date = 940415 ; 660 strcpy(pptr->dest, "CHITOSE") ; 670 pptr->departure = 1540 ; 680 pptr->status = 0 ; 690 /* 700 * TPACALL(サービスリクエストを送信する) 710 */ 720 cd = tpacall("SVHOTEL", (char *) hptr, 0, 0); 730 if(cd == -1){ 740 printf("宿泊施設空状況検索サービスの呼び出しに失敗しました。\ 750 ERROR CODE = %d \n", tperrno); 760 goto PROG_END; 770 } 780 printf("宿泊施設空状況検索サービスの呼び出しに成功しました。\n"); 790 /* 800 * TPCALL(サービスリクエストを送信して,応答を待つ) 810 */ 820 rc = tpcall("SVPLANE", (char *) pptr, 0, (char **) &pptr, &plen, 0); 830 if(rc != 0){ 840 if(tperrno == TPESVCFAIL){ 850 werrmsg = (struct errmsg *) pptr ; 860 printf("%s ERROR CODE = %d USER CODE = %d\n", 870 werrmsg->errmessage, tperrno, tpurcode); 880 goto PROG_END ; 890 }else{ 900 printf("飛行機空き状況検索サービスの呼び出しに失敗しました。 \ 910 ERROR CODE = %d", tperrno); 920 goto PROG_END; 930 } 940 } 950 printf("飛行機空き状況検索サービスの呼び出しの応答受信に成功しました。\n"); 960 if(pptr->status == 1){ 970 printf("飛行機空き状況 : 満席です。 \n"); 980 } else { 990 printf("飛行機空き状況 : 空席があります。 \n"); 1000 } 1010 /* 1020 * TPGETRPLY(応答を受信する) 1030 */ 1040 rc = tpgetrply(&cd, (char **) &hptr, &hlen, 0); 1050 if(rc != 0){ 1060 if(tperrno == TPESVCFAIL){ 1070 werrmsg = (struct errmsg *) hptr ; 1080 printf("%s ERROR CODE = %d USER CODE = %d\n", 1090 werrmsg->errmessage, tperrno, tpurcode); 1100 goto PROG_END ; 1110 }else{ 1120 printf("宿泊施設空状況検索サービスに失敗しました。 \ 1130 ERROR CODE = %d", tperrno); 1140 goto PROG_END; 1150 } 1160 } 1170 printf("宿泊施設空状況検索サービスの応答受信に成功しました。\n"); 1180 if(hptr->status == 1){ 1190 printf("宿泊施設空き状況 : 満室です。 \n"); 1200 } else { 1210 printf("宿泊施設空き状況 : 空室があります。 \n"); 1220 } 1230 /* 1240 * 型付きバッファの解放 1250 */ 1260 tpfree((char *) hptr); 1270 tpfree((char *) pptr); 1280 /* 1290 * RPC-CLOSE(UAPの終了) 1300 */ 1310 PROG_END: 1320 dc_rpc_close(DCNOFLAGS); 1330 printf("またのご利用をお待ちしています。\n"); 1340 exit(0); 1350 }
-
ユーザサービス定義の例
リクエスト/レスポンス型サービスの例題で示すSUPのユーザサービス定義例を次に示します。
10 #ユーザサービス定義の例(rrsupファイル) 20 set module = "rrsup" 30 set receive_from = none 40 set trn_expiration_time = 180 50 set trn_expiration_time_suspend = Y 60 set xat_osi_usr = Y
(e) SPPの例
-
XATMIインタフェース定義の例
リクエスト/レスポンス型サービスの例題で示すSPPのXATMIインタフェース定義を次に示します。
10 /* XATMIインタフェース定義の例(rrspp.defファイル)*/ 20 X_COMMON hotel { 30 long date; 40 char place[128]; 50 char hname[128]; 60 long status; 70 }; 80 X_COMMON plane { 90 long date; 100 char dest[128]; 110 long departure; 120 long status; 130 }; 140 X_COMMON errmsg { 150 char errmessage[128]; 160 }; 170 service shotel(X_COMMON hotel) ; 180 service splane(X_COMMON plane) ;
-
SPPのコーディング例(メイン関数)
リクエスト/レスポンス型サービスの例題で示すSPPのコーディング例(メイン関数)を次に示します。
10 /* SPPのメイン関数例(rrspp.cファイル)*/ 20 #include <stdio.h> 30 #include <stdlib.h> 40 #include <dcrpc.h> 50 #include <xatmi.h> 60 #include <dcadm.h> 70 /* 80 * XATMIスタブヘッダファイル 90 */ 100 #include "rrspp_stbx.h" 110 main() 120 { 130 /* 140 * 変数の定義 150 */ 160 int rc; 170 /* 180 * RPC-OPEN(UAPの開始) 190 */ 200 rc = dc_rpc_open(DCNOFLAGS); 210 if(rc != DC_OK){ 220 printf("dc_rpc_openに失敗しました。\ 230 ERROR CODE = %d \n", rc); 240 goto PROG_END; 250 } 260 /* 270 * RPC-MAINLOOP(SPPのサービス開始) 280 */ 290 rc = dc_rpc_mainloop(DCNOFLAGS); 300 if(rc != DC_OK){ 310 printf("dc_rpc_mainloopに失敗しました。\ 320 ERROR CODE = %d \n", rc); 330 } 340 /* 350 * RPC-CLOSE(UAPの終了) 360 */ 370 PROG_END: 380 dc_rpc_close(DCNOFLAGS); 390 exit(0); 400 }
-
SPPのコーディング例(サービス関数)
リクエスト/レスポンス型サービスの例題で示すSPPのコーディング例(サービス関数)を次に示します。
10 /* SPPのサービス関数例(rrsvc.cファイル)*/ 20 #include <stdio.h> 30 #include <dcrpc.h> 40 #include <xatmi.h> 50 #include <dcadm.h> 60 /* 70 * XATMIスタブヘッダファイル 80 */ 90 #include "rrspp_stbx.h" 100 void shotel(svcinfo) 110 TPSVCINFO *svcinfo; 120 { 130 /* 140 * 変数の定義 150 */ 160 struct hotel *hptr; 170 180 hptr = (struct hotel *) svcinfo->data; 190 /* このサービスは空き状況を検索して,満室ならば status = 1 , 200 * 空室があれば status = 0,エラーが起こったときは,メッセージを返します。 210 * ここでは,検索した結果,満室だったとします。*/ 220 hptr->status = 1 ; 230 tpreturn(TPSUCCESS, 0, (char *)hptr, 0, 0); 240 return ; /* OpenTP1の場合はtpreturn後にreturnの発行が必要です。 */ 250 } 260 void splane(svcinfo) 270 TPSVCINFO *svcinfo; 280 { 290 struct plane *pptr; 300 pptr = (struct plane *) svcinfo->data; 310 /* このサービスは空き状況を検索して,満席ならば status = 1, 320 * 空席があれば status = 0 ,エラーが起こったときは,メッセージを返します。 330 * ここでは,検索した結果,満席だったとします。*/ 340 pptr->status = 1 ; 350 tpreturn(TPSUCCESS, 0, (char *)pptr, 0, 0); 360 return ; 370 }
-
ユーザサービス定義の例
リクエスト/レスポンス型サービスの例題で示すSPPのユーザサービス定義例を次に示します。
10 #ユーザサービス定義の例(rrsppファイル) 20 set service_group = "rrspp_svg" 30 set module = "rrspp" 40 set service = "SVHOTEL=shotel","SVPLANE=splane" 50 set trn_expiration_time = 180 60 set trn_expiration_time_suspend = Y 70 set server_type = "xatmi" 80 set xat_osi_usr = Y
(2) 会話型サービスの通信の例
(a) 処理の概要
ここで示す例題の処理概要を,次に説明します。
[説明]acctreq構造体の構造を持つ型付きバッファでサービス関数を起動します。acctreqのメンバは口座番号の上限と下限を示します。サービス関数では,この範囲にある口座データをacctdata構造体の構造を持つ型付きバッファに設定して,会話のオリジネータに送信します。
(b) UAPの構成
例題のUAPの構成を次の図に示します。
(c) 通信に使う型付きバッファ
通信に使う型付きバッファの構造体を次に示します。
-
サービス関数起動時のデータ
struct acctreq{ DCLONG upper_no; DCLONG lower_no; }
-
会話型サービスの通信をするときのデータ
struct acctdata{ DCLONG acct_no; char name[128]; short amount; char dc_dummy0[2]; }
(d) SUPの例
-
XATMIインタフェース定義の例
会話型サービスの例題で示すSUPのXATMIインタフェース定義を次に示します。
10 /* SUPのXATMIインタフェース定義の例(convsup.defファイル)*/ 20 called_servers = { "convspp.def" };
-
SUPのコーディング例
会話型サービスの例題で示すSUPのコーディング例を次に示します。
10 /* SUPのコーディング例(convsup.cファイル)*/ 20 #include <stdio.h> 30 #include <stdlib.h> 40 #include <dcrpc.h> 50 #include <xatmi.h> 60 #include <tx.h> 70 #include <dcadm.h> 80 /* 90 * XATMIスタブヘッダファイル 100 */ 110 #include "convsup_stbx.h" 120 main() 130 { 140 /* 150 * 変数の定義 160 */ 170 struct acctreq *rptr; 180 struct acctdata *dptr; 190 long wlen; 200 int cd; 210 int rc; 220 long revent; 230 long size = 0 ; 240 /* 250 * RPC-OPEN(UAPの開始) 260 */ 270 rc = dc_rpc_open(DCNOFLAGS); 280 if(rc != DC_OK){ 290 printf("dc_rpc_openに失敗しました。ERROR CODE = %d \n", rc); 300 goto PROG_END; 310 } 320 /* 330 * ADM-COMPLETE(ユーザサーバの開始処理完了の報告) 340 */ 350 rc = dc_adm_complete(DCNOFLAGS); 360 if(rc != DC_OK){ 370 printf("dc_adm_completeに失敗しました。ERROR CODE = %d \n", rc); 380 goto PROG_END; 390 } 400 /* 410 * TPALLOC(型付きバッファの確保) 420 */ 430 /*サーチする口座番号の上限,下限の設定用*/ 440 rptr = (struct acctreq *)tpalloc(X_COMMON, "acctreq", 0); 450 460 if(rptr == NULL){ 470 printf("tpallocに失敗しました。ERROR CODE = %d \n", tperrno); 480 goto PROG_END; 490 } 500 /*サーチ結果の口座データ用*/ 510 dptr = (struct acctdata *)tpalloc(X_COMMON, "acctdata", 0) ; 520 if(dptr == NULL){ 530 printf("tpallocに失敗しました。ERROR CODE = %d \n", tperrno); 540 goto PROG_END; 550 } 560 /* 570 * データの設定 580 * サーチする範囲を指定 590 */ 600 rptr->lower_no = 10000000L; 610 rptr->upper_no = 20000000L; 620 /* トランザクション開始 */ 630 tx_begin() ; 640 /* 650 * TPCONNECT(会話サービスの呼び出し) 660 * INQUIRYを呼ぶ。 670 */ 680 cd = tpconnect("INQUIRY", (char *) rptr, 0, TPRECVONLY); 690 if(cd == -1){ 700 printf("tpconnectに失敗しました。ERROR CODE = %d \n", tperrno); 710 goto PROG_END; 720 } 730 /* 740 * エラーが起こるまで(イベントの発生も含む), 750 * TPRECV(メッセージを受信) 760 */ 770 while(rc != -1){ 780 rc = tprecv(cd, (char **) &dptr, &wlen, 0, &revent); 790 /* 800 *エラーが起こっていなければ, 810 *受信した口座情報を出力する。 820 */ 830 if(rc != -1) { 840 printf("サービスから口座情報を受信しました。\n"); 850 printf("口座番号 = %d \n", dptr->acct_no); 860 printf("名前 = %s \n", dptr->name); 870 printf("預金 = %d \n", dptr->amount); 880 } 890 } 900 /* 910 * サービスの結果の出力 920 */ 930 if(tperrno == TPEEVENT){ 940 if(revent == TPEV_SVCSUCC){ 950 /* サービスは成功した。*/ 960 printf("サービスは成功しました。\n"); 970 /* トランザクションのコミット */ 980 tx_commit() ; 990 }else{ 1000 printf("何らかのイベントが発生しています。revent = %d\n", 1010 revent); 1020 /* トランザクションのロールバック*/ 1030 tx_rollback() ; 1040 } 1050 } 1060 /* 1070 * 型付きバッファの解放 1080 */ 1090 tpfree((char *) rptr); 1100 tpfree((char *) dptr); 1110 /* 1120 * RPC-CLOSE(UAPの終了) 1130 */ 1140 PROG_END: 1150 dc_rpc_close(DCNOFLAGS); 1160 exit(0); 1170 }
-
ユーザサービス定義の例
会話型サービスの例題で示すSUPのユーザサービス定義例を次に示します。
10 #ユーザサービス定義の例(convsupファイル) 20 set module = "convsup" #実行形式ファイル名 30 set watch_time = 180 #最大応答待ち時間 40 set receive_from = none #受信方法 50 set trn_expiration_time = 180 60 #トランザクションブランチ限界経過時間 70 set trn_expiration_time_suspend = Y #必ず Y を指定
(e) SPPの例
-
XATMIインタフェース定義の例
会話型サービスの例題で示すSPPのXATMIインタフェース定義を次に示します。
10 /* SPPのXATMIインタフェース定義の例(convspp.defファイル)*/ 20 X_COMMON acctreq { 30 long upper_no; 40 long lower_no; 50 }; 60 X_COMMON acctdata { 70 long acct_no; 80 char name[128]; 90 short amount; 100 }; 110 service inquiry(X_COMMON acctreq) ;
-
SPPのコーディング例(メイン関数)
会話型サービスの例題で示すSPPのコーディング例(メイン関数)を次に示します。
10 /* SPPのメイン関数例(convspp.cファイル)*/ 20 #include <stdio.h> 30 #include <stdlib.h> 40 #include <dcrpc.h> 50 #include <xatmi.h> 60 #include <dcadm.h> 70 /* 80 * XATMIスタブヘッダファイル 90 */ 100 #include "convspp_stbx.h" 110 main() 120 { 130 /* 140 * 変数の定義 150 */ 160 int rc; 170 /* 180 * RPC-OPEN(UAPの開始) 190 */ 200 rc = dc_rpc_open(DCNOFLAGS); 210 if(rc != DC_OK){ 220 printf("dc_rpc_openに失敗しました。ERROR CODE = %d \n", rc); 230 goto PROG_END; 240 } 250 260 /* 270 * RPC-MAINLOOP(SPPのサービス開始) 280 */ 290 rc = dc_rpc_mainloop(DCNOFLAGS); 300 if(rc != DC_OK){ 310 printf("dc_rpc_mainloopに失敗しました。ERROR CODE = %d \n",rc); 320 } 330 /* 340 * RPC-CLOSE(UAPの終了) 350 */ 360 PROG_END: 370 dc_rpc_close(DCNOFLAGS); 380 exit(0); 390 }
-
SPPのコーディング例(サービス関数)
会話型サービスの例題で示すSPPのコーディング例(サービス関数)を次に示します。
10 /* SPPのサービス関数例(convsvc.cファイル)*/ 20 #include <stdio.h> 30 #include <stdlib.h> 40 #include <string.h> 50 #include <dcrpc.h> 60 #include <xatmi.h> 70 #include <dcadm.h> 80 /* 90 * XATMIスタブヘッダファイル 100 */ 110 #include "convspp_stbx.h" 120 /* 130 * DEPOSITSVC サービス関数 140 * tpconnect()によって口座番号の上限,下限を受取り 150 * その範囲にある口座の情報を送信する。 160 */ 170 void inquiry(svcinfo) 180 TPSVCINFO *svcinfo; 190 { 200 /* 210 * 変数の定義 220 */ 230 struct acctreq *rptr; 240 struct acctdata *dptr; 250 char type[9]; 260 char subtype[17]; 270 long revent, rval; 280 int size; 290 /* 300 * サービス要求が受け付けられた 310 */ 320 rptr = (struct acctreq *) svcinfo->data; 330 /* 340 * オリジネータに返すデータのtypedバッファの確保 350 */ 360 dptr = (struct acctdata *)tpalloc("X_COMMON", "acctdata", 0); 370 if(dptr == NULL){ 380 printf("tpallocでエラーが起こりました。tperrno = %d \n", 390 tperrno); 400 abort(); 410 } 420 /* 430 * ユーザ処理 440 * データファイルを検索して口座番号が範囲内の口座情報を返す。 450 * ここでは2件見つかったこととしてデータを送信する。 460 */ 470 480 dptr->acct_no = 10000001L; 490 strcpy(dptr->name, "Hitachi Hanako"); 500 dptr->amount = 20000; 510 /* 520 * TPSEND(メッセージの送信) 530 */ 540 tpsend(svcinfo->cd, (char *) dptr, 0, 0, &revent); 550 if(tperrno != -1){ 560 rval = TPSUCCESS; 570 }else{ 580 rval = TPFAIL; 590 goto SVC_END; 600 } 610 dptr->acct_no = 10000002L; 620 dptr->amount = 10000; 630 strcpy(dptr->name, "Hitachi Tarou"); 640 /* 650 * TPSEND(メッセージの送信) 660 */ 670 tpsend(svcinfo->cd, (char *) dptr, 0, 0, &revent); 680 if(tperrno != -1){ 690 rval = TPSUCCESS; 700 }else{ 710 rval = TPFAIL; 720 goto SVC_END; 730 } 740 SVC_END: 750 tpreturn(rval, 0, NULL, 0, 0); 760 return; /* OpenTP1の場合 tpreturn後にreturnが必要です。*/ 770 }
-
ユーザサービス定義の例
会話型サービスの例題で示すSPPのユーザサービス定義例を次に示します。
10 # ユーザサービス定義の例(convsppファイル) 20 set service_group = "convspp_svg" #サービスグループ名 30 set module = "convspp" #実行形式ファイル名 40 set service = "INQUIRY=inquiry" 50 #サービス名=エントリポイント名 60 set watch_time = 180 #最大応答待ち時間 70 set trn_expiration_time = 240 80 #トランザクションブランチ限界経過時間 90 set trn_expiration_time_suspend = Y #必ず Y を指定 100 set server_type = "xatmi" #サーバタイプ 110 set receive_from = "socket" #受信方法