1 方向性メッセージングでは、クライアントスレッドがメッセージを含むリクエストをサーバーに送信します。クライアントスレッドはサーバーからの応答を待つことなく、その要求がトランスポート層に受け入れられたら処理を進めることができます。そのリクエ ストはトランスポート層によって常にすぐサーバーに送信されるとは限りませんが、トランスポート層に送信されるまでキューで待機します。サーバーは、リクエスト内に含まれるメッセージを処理することによって、受け取ったリクエストを実行します。
トランスポート層がリクエストを受け取った後は、クライアントは転送の失敗を通知されることはなく、またサーバーからリクエストを受け取った旨を通知されることもありません。たとえば、サーバーが認証上の問題によりリクエストを拒否した場合は、クライアントはこの問題を通知されることはありません。トランスポート層がリクエストを受け入れなかった場合は、送信オペレーションにより直ちにエラーがクライアントに返されます。
サーバーが正しく機能していることをチェックする必要がある場合は、2 方向性のリクエストをサーバーに送信してみます。このリクエストにより、サーバーが利用可能であり、クライアントから送信された 1 方向性リクエストをサーバーが受信中かを判定することができます。
1 方向性のメッセージングには、clnt_send() 関数が Sun RPC ライブラリに追加され、oneway 属性が RPC 文法に追加されています。
Sun RPC ライブラリの以前のバージョンでは、リモートプロシージャコールの送信に clnt_call() 関数を使用していました。拡張された 1 方向性のメッセージングサービスでは、clnt_send() 関数が 1 方向性のリモートプロシージャコールを送信します。
クライアントが clnt_send() を呼び出す際は、クライアントはサーバーにリクエストを送信し、処理を続行します。リクエストがサーバーに到着すると、サーバーは着信リクエストを処理するためにディスパッチルーチンを呼び出します。
clnt_send() 関数は、clnt_call() と同様、サービスへアクセスするためにクライアントハンドルを使用します。詳細は、clnt_send(3NSL) および clnt_call(3NSL) のマニュアルページを参照してください。
clnt_create() に適切なバージョン番号を指定しない場合、clnt_call() は失敗します。clnt_send() は、サーバーがステータスを返さないため、同じ状況では失敗を報告しません。
1 方向性メッセージングを使用するには、oneway キーワードをサーバー関数の XDR 定義に追加します。oneway キーワードを使用する場合は、rpcgen によって生成されるスタブは clnt_send() を使用します。ユーザーは次のいずれかを行うことができます:
『ONC+ 開発ガイド』の「TI-RPC 入門」セクションに概説されている、単純インタフェースを使用します。単純インタフェースに使用されるスタブは clnt_send() を呼び出す必要があります。
clnt_send(3NSL) のマニュアルページに記述されているように、clnt_send() 関数を直接呼び出します。
1 方向性メッセージングには、rpcgen コマンドのバージョン 1.1 を使用してください。
oneway キーワードを宣言する際は、次の構文を使用する RPC 言語の仕様に従ってください:
"oneway" function-ident "(" type-ident-list ")" "=" value;RPC 言語の仕様についての詳細は、『ONC+ 開発ガイド』の「RPC プロトコルおよび言語の仕様」のセクションを参照してください。
オペレーションに oneway 属性を宣言する際は、サーバーサイドには何の結果も作成されず、クライアントには何のメッセージも返されません。
oneway 属性の情報は、表 1–1 に示すように、『ONC+ 開発ガイド』の「RPC 言語の仕様」セクションの「RPC 言語定義」の表に追加されていなければなりません。
表 1–1 RPC 言語定義
用語 |
定義 |
---|---|
プロシージャ (手続き) |
type-ident procedure-ident (type-ident) = value oneway procedure-ident (type-ident) = value |
この例は、単純なカウンターサービスにおいて 1 方向性のプロシージャを使用する方法を例示しています。このカウンターサービスでは、ADD() 関数が、使用できる唯一の関数です。各リモートコールは整数を送信し、この整数は、サーバーによって管理されるグローバルカウンターに追加されます。このサービスを使用するためには、表 1–1 に記述されているように、RPC 言語定義に oneway 属性を宣言する必要があります。
この例では、-M、-N、および -C rpcgen オプションを使用してスタブを生成します。これらのオプションにより確実に、スタブがマルチスレッド-安全で、複数の入力パラメータを受け入れ、生成されたヘッダーが ANSI C++ に適合するようになります。スタブが変わらないので引数を渡すセマンティクスがよりクリアであり、アプリケーションへのスレッドの追加がより簡単になるため、クライアントおよびサーバーアプリケーションがシングルスレッドであっても、これらの rpcgen オプションを使用してください。
counter.x ファイルにサービスの記述を書きます。
/* counter.x: リモートカウンタープロトコル */ program COUNTERPROG { version COUNTERVERS { oneway ADD(int) = 1; } = 1; } = 0x20000001;
このサービスは、プログラム番号 (COUNTERPROG) 0x200000001、バージョン番号 (COUNTERVERS) 1 を持ちます。
counter.x ファイルに rpcgen を呼び出します。
rpcgen -M -N -C counter.xこれにより、クライアントおよびサーバーのスタブ counter.h、counter_clnt.c、counter_svc.c が生成されます。
server.c ファイルに示されているように、サーバーサイド用のサービスハンドラ、およびハンドラに割り当てられたメモリー領域を解放するために使用される counterprog_1_freeresult() 関数を記述します。サーバーがクライアントへ応答を送信する時に、RPC ライブラリがこの関数を呼び出します。
#include <stdio.h> #include "counter.h" int counter = 0; bool_t add_1_svc(int number, struct svc_req *rqstp) { bool_t retval = TRUE; counter = counter + number; return retval; } int counterprog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, caddr_t result) { (void) xdr_free(xdr_result, result); /* * 必要であれば、ここに解放のための追加コードを挿入する */ return TRUE; }
サービスハンドラ、counter_svc.c スタブをコンパイルおよびリンクして、サーバーを構築します。このスタブには、TI-RPC の初期化および処理に関する情報が含まれています。
クライアントアプリケーション client.c を記述します。
#include <stdio.h> #include "counter.h" main(int argc, char *argv[]) { CLIENT *clnt; enum clnt_stat result; char *server; int number; if(argc !=3) { fprintf(stderr, "usage: %s server_name number\n", argv[0]; exit(1); } server = argv[1]; number = atoi(argv[2]); /* * クライアントハンドルを作成する */ clnt = clnt_create(server, COUNTERPROG, COUNTERVERS, "tcp"); if(clnt == (CLIENT *)NULL) { /* * 接続を確立できなかった */ clnt_pcreateerror(server); exit(1); } result = add_1(number, clnt); if (result !=RPC_SUCCESS) { clnt_perror(clnt, "call failed"); } clnt_destroy(clnt); exit(0); }
add_1() クライアント関数は、リモート関数用に生成された counter_clnt.c スタブです。
クライアントを構築するには、クライアントの main および counter_clnt.c をコンパイルおよびリンクします。
構築したサーバーを起動します。
% ./server
別のシェルでサービスを呼び出します。
% ./client servername 23
23 は、グローバルカウンターに追加される番号です。