場合によっては、動的に生成される RPC プログラム番号をアプリケーションが使用すると便利なことがあります。たとえば、コールバック手続きを実装する場合などです。コールバックでは、クライアントプログラムは通常、動的に生成される、つまり一時的な RPC プログラム番号を使用して RPC サービスを登録します。そして、その番号を要求とともにサーバーに渡します。次にサーバーは一時的な RPC プログラム番号を使用してクライアントプログラムをコールバックし、結果を返します。
クライアントの要求を処理するのにかなりの時間がかかり、クライアントが停止できない場合 (シングルスレッドであると思われるとき) には、この機構が必要になります。このような場合、サーバーはクライアントの要求を認識し、あとで結果とともにコールバックを行います。
コールバックを使用する別の例としては、サーバーから定期的なレポートを生成する場合があります。クライアントは RPC 呼び出しを行い、報告を開始します。そしてサーバーはクライアントプログラムが提供する一時的な RPC プログラム番号を使用して、定期的にレポートとともにクライアントをコールバックします。
動的に生成される一時的な RPC 番号は、0x40000000 から 0x5fffffff の範囲です。次に示すルーチンは指定されるトランスポートタイプ用に、一時的な RPC プログラムに基づいてサービスを作成します。サービスハンドルと一時的な RPC プログラム番号が返されます。呼び出し側はサービスディスパッチルーチン、バージョンタイプ、トランスポートタイプを提供します。
SVCXPRT *
register_transient_prog(dispatch, program, version, netid)
void (*dispatch)(); /* サービスディスパッチルーチン */
rpcproc_t *program; /* 一時的な RPC 番号が返される */
rpcvers_t version; /* プログラムバージョン */
char *netid; /* トランスポート id */
{
SVCXPRT *transp;
struct netconfig *nconf;
rpcprog_t prognum;
if ((nconf = getnetconfigent(netid)) == (struct netconfig
*)NULL)
return ((SVCXPRT *)NULL);
if ((transp = svc_tli_create(RPC_ANYFD, nconf,
(struct t_bind *)NULL, 0, 0)) == (SVCXPRT *)NULL) {
freenetconfigent(nconf);
return ((SVCXPRT *)NULL);
}
prognum = 0x40000000;
while (prognum < 0x60000000 && svc_reg(transp, prognum,
version,
dispatch, nconf) == 0) {
prognum++;
}
freenetconfigent(nconf);
if (prognum>= 0x60000000) {
svc_destroy(transp);
return ((SVCXPRT *)NULL);
}
*program = prognum;
return (transp);
}
|