![]() |
iPlanet Calendar Server プログラマリファレンス |
第 5 章 イベント通知サービス API リファレンス
この章では、ENS API について説明します。この章は次の 4 つの節に分かれています。
パブリッシャ API
パブリッシャ API の関数リスト
パブリッシャ関数について、次の 表 5-1 で説明します。
サブスクライバ API の関数リスト
サブスクライバ関数について、次の表 5-2 で説明します。
公開および購読ディスパッチャーの関数リスト
公開および購読ディスパッチャー関数について、次の表 5-3 で説明します。
表 5-3 ENS 公開および購読ディスパッチャーの関数リスト
パブリッシャ API は、次の 1 つの定義と 9 つの関数から構成されています。
publisher_t
構文
typedef struct enc_struct publisher_t;
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
非同期呼び出しの結果を確認するため、ENS によって呼び出される汎用コールバック関数
構文
typedef void (*publisher_cb_t) (void *arg, int rc, void *data);
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void publisher_new_a (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port,
publisher_cb_t cbdone,
void *cbarg);
パラメータ
アプリケーションワーカー。NULL 以外の場合、ENS によって作成された既存のワーカーにグループ化され、現在のパブリッシャセッションで使用される。これは、複数のスレッドによってパブリッシャデータが同時にアクセスされるのを防ぐために使用される
戻り値
なし。cbdone コールバックの 3 番目の引数として、新規アクティブパブリッシャが渡されます。
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
publisher_t *publisher_new_s (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port);
パラメータ
アプリケーションワーカー。NULL 以外の場合、ENS によって作成された既存のワーカーにグループ化され、現在のパブリッシャセッションで使用される。また、複数のスレッドによってパブリッシャデータが同時にアクセスされることを防ぐために使用する
戻り値
新規アクティブパブリッシャ (publisher_t)
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void publish_a (publisher_t *publisher,
const char *event_ref,
const char *data,
unsigned int datalen,
publisher_cb_t cbdone,
publisher_cb_t end2end_ack,
void *cbarg,
unsigned long timeout);
パラメータ
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
int publish_s (publisher_t *publisher,
const char *event_ref,
const char *data,
unsigned int datalen);
パラメータ
イベントデータ。通知メッセージの本文。MIME オブジェクトであることが必要。通知サービスに対して不透明で、通知サービスはイベントのサブスクライバへの中継だけを行う
戻り値
成功した場合はゼロ、失敗した場合は障害コード。RENL の場合、サブスクライバが通知を完全に処理し、送達確認が完了するまで、呼び出しは返されません。
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void publisher_delete (publisher_t *publisher);
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
パブリッシャの証明書を使ってサブスクライバを作成します。
構文
struct subscriber_struct * publisher_get_subscriber(publisher_t *publisher);
戻り値
作成に成功した場合はそのサブスクライバ、失敗した場合は NULL。作成に失敗した場合は、subscriber_new を使用してサブスクライバを作成します。
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
RENL を宣言します。これにより end2end_ack の呼び出しが有効になります。この呼び出しが返されたあとは、指定されたパブリッシャおよびサブスクライバに対応する送達確認が受信されたときに、end2end_ack 引数が呼び出されます。
構文
void renl_create_publisher (publisher_t *publisher,
const char *renl_id,
const char *subscriber,
publisher_cb_t cbdone,
void *cbarg);
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
RENL をキャンセルします。キャンセルしても、通知は送信されます。ただし、クライアントの送達確認が着信しても、パブリッシャの end2end_ack 引数は呼び出されません。パブリッシャを削除すると、RENL がすべて自動的に削除されます。このため、パブリッシャを削除する前に、この関数を呼び出して RENL 関連のメモリを解放する必要はありません。
構文
void renl_cancel_publisher (renl_t *renl);
[パブリッシャ API 一覧に戻る]
[第 5 章の先頭に戻る]
サブスクライバ API は、次の 2 つの定義と 10 の関数から構成されています。
subscriber_t
構文
typedef struct enc_struct subscriber_t;
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
typedef struct subscription_struct subscription_t;
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
非同期呼び出しの結果を確認するために、ENS によって呼び出される汎用コールバック関数
構文
typedef void (*subscriber_cb_t) (void *arg,
int rc,
void *data);
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
typedef void (*subscriber_notify_cb_t) (void *arg,
char *event,
char *data,
int datalen);
パラメータ
イベント参照 (URI)。この通知イベント参照は購読と対応する。ただし、uid などのイベント属性と呼ばれる情報が追加されている場合もある
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void subscriber_new_a (pas_dispatcher_t *disp,
void *worker,
const char *host,
unsigned short port,
subscriber_cb_t cbdone,
void *cbarg);
パラメータ
アプリケーションワーカー。NULL 以外の場合、ENS によって作成された既存のワーカーにグループ化され、現在のサブスクライバセッションで使用される。また、複数のスレッドによってサブスクライバデータが同時にアクセスされるのを防ぐために使用する。呼び出し元が GDisp コンテキストを作成して振り分ける場合にだけ使用できる
戻り値
なし。cbdone コールバックの 3 番目の引数として、新規アクティブサブスクライバが渡されます。
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
subscriber_t *subscriber_new_s (pas_dispatcher_t *disp,
const char *host,
unsigned short port);
パラメータ
アプリケーションワーカー。NULL 以外の場合、ENS によって作成された既存のワーカーにグループ化され、現在のパブリッシャセッションで使用される。また、複数のスレッドによってパブリッシャデータが同時にアクセスされるのを防ぐために使用する。呼び出し元が GDisp コンテキストを作成して振り分ける場合にだけ使用できます
戻り値
新規アクティブサブスクライバ (subscriber_t)
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void subscribe_a (subscriber_t *subscriber,
const char *event_ref,
subscriber_notify_cb_t notify_cb,
void *notify_arg,
subscriber_cb_t cbdone,
void *cbarg):
パラメータ
notify_arg の最初の引数。サブスクライバはアクティブな状態のまま、任意のスレッドから任意のタイミングに呼び出される場合がある
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void unsubscribe_a (subscriber_t *subscriber,
subscription_t *subscription,
subscriber_cb_t cbdone,
void *cbarg);
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
void subscriber_delete (subscriber_t *subscriber);
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
サブスクライバの証明書を使ってパブリッシャを作成します。
構文
struct publisher_struct *subscriber_get_publisher (subscriber_t *subscriber);
戻り値
作成に成功した場合はそのパブリッシャ、失敗した場合は NULL。作成に失敗した場合は、publisher_new を使用してサブスクライバを作成します。
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
renl_t *renl_create_subscriber (subscription_t *subscription,
const char *renl_id,
const char *publisher);
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
RENL をキャンセルします。ただし、購読はキャンセルされません。この購読に対して以降の送信確認が行われないことを ENS に知らせます。この関数により、RENL オブジェクトが破棄されるため、アプリケーションはこの RENL をそれ以降使用できなくなります。購読をキャンセルすると、RENL はすべて自動的に削除されます。このため、サブスクライバを削除する前に、この関数を呼び出して RENL 関連のメモリを解放する必要はありません。
構文
void renl_cancel_subscriber (renl_t *renl);
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
公開および購読ディスパッチャー API は、次の 1 つの定義と 4 つの関数から構成されています。
構文
typedef struct pas_dispatcher_struct pas_dispatcher_t;
[サブスクライバ API 一覧に戻る]
[第 5 章の先頭に戻る]
構文
pas_dispatcher_t *pas_dispatcher_new (void *disp);
パラメータ
ディスパッチャーコンテキスト。NULL の場合、通知のディスパッチを開始するには、アプリケーションから pas_dispatch を呼び出す必要がある
戻り値
パブリッシャまたはサブスクライバを作成するときに使用するディスパッチャー (pas_dispatcher_t)
[公開および購読ディスパッチャー API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
pas_dispatcher_new で作成したディスパッチャーを削除します。
構文
void pas_dispatcher_delete (pas_dispatcher_t *disp);
[公開および購読ディスパッチャー API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
イベント通知環境のディスパッチループを開始します。アプリケーションで独自のスレッドプールを使用している場合は何も起きません。
構文
void pas_dispatch (pas_dispatcher_t *disp);
[公開および購読ディスパッチャー API 一覧に戻る]
[第 5 章の先頭に戻る]
目的
pas_dispatch で開始したイベント通知環境のディスパッチループを停止します。アプリケーションが提供したディスパッチャーを pas_dispatcher_new に渡していた場合には何も起きません。
構文
void pas_shutdown (pas_dispatcher_t *disp);
[公開および購読ディスパッチャー API 一覧に戻る]
[第 5 章の先頭に戻る]
コーディング例
iPlanet Calendar Server には完全な ENS 実装が付属しています。必要であれば、これらの API を使用して ENS をカスタマイズできます。次の 4 つのコードサンプル (簡単なパブリッシャとサブスクライバ、および信頼性の高いパブリッシャとサブスクライバ) は、API の使い方を示しています。コーディング例は、この製品の次のディレクトリにあります。/opt/SUNWics5/cal/csapi/samples/ens
簡単なパブリッシャとサブスクライバ
これらのコーディング例では、簡単な連携動作する非同期パブリッシャおよびサブスクライバを確立します。
パブリッシャのコードサンプル
/*
* Copyright 2000 by Sun Microsystems, Inc.
* All rights reserved
*
* apub :簡単な連携動作する非同期パブリッシャ
*
* 構文 :
* apub ホスト名 ポート番号
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "publisher.h"static pas_dispatcher_t *disp = NULL;
static publisher_t *_publisher = NULL;
static int _shutdown = 0;static void _exit_usage()
{
printf("\n使用法 :\napub ホスト名 ポート番号\n");
exit(5);
}static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _call_shutdown()
{
_shutdown = 1;
pas_shutdown(disp);
}static void _open_ack(void *arg, int rc, void *enc)
{
_publisher = (publisher_t *)enc;
(void *)arg;if (!_publisher)
{
printf("状態 %d のため、パブリッシャの作成に失敗しました\n", rc);
_call_shutdown();
return;
}static void _publish_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;printf("状態 %d のため、公開に失敗しました\n", rc);
if ( !fgets(input, sizeof(input), stdin) )
{
continue;} else {
char *message;
unsigned int message_len;input[strlen(input) - 1] = 0; /* Strip off the \n */
if (*input == '.' && input[1] == 0)
{
publisher_delete(_publisher);
_call_shutdown();
break;
}message = strdup(input);
message_len = strlen(message);
publish(_publisher, "enp://yoyo.com/xyz",message,
message_len,
_publish_ack, NULL, (void *)message, 0);
return;
}
}
return;
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];if (*(argv[1]) == '0')
{
strcpy(host, "127.0.0.1");
} else {
strcpy(host, argv[1]);
}if (argc > 2)
{
port = (unsigned short)atoi(argv[2]);
}disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("ディスパッチャーを作成できません");publisher_new_a(disp, NULL, host, port, _open_ack, disp);
サブスクライバのコードサンプル
/*
* Copyright 1997 by Sun Microsystems, Inc.
* All rights reserved
*
* asub :非同期サブスクライバの例
*
* 構文 :
* asub ホスト名 ポート番号
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "subscriber.h"static pas_dispatcher_t *disp = NULL;
static subscriber_t *_subscriber = NULL;
static subscription_t *_subscription = NULL;
static renl_t *_renl = NULL;static void _exit_usage()
{
printf("\n使用法 :\nasub ホスト名 ポート番号\n");
exit(5);
}static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _subscribe_ack(void *arg, int rc, void *subscription)
{
(void)arg;if (!rc)
{
_subscription = subscription;
printf("購読依頼に成功しました\n");
} else {
printf("購読依頼に失敗しました - 状態 %d\n", rc);
pas_shutdown(disp);
}
}static void _unsubscribe_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;
(void *)arg;if (rc != 0)
{
printf("購読の中止に失敗しました - 状態 %d\n", rc);
}subscriber_delete(_subscriber);
pas_shutdown(disp);
}static int _handle_notify(void *arg, char *url, char *str, int len)
{
(void *)arg;
printf("[%s] %.*s\n", url, len, (str) ? str : "(null)");
return 0;
}static void _open_ack(void *arg, int rc, void *enc)
{
_subscriber = (subscriber_t *)enc;(void *)arg;
if (rc)
{
printf("状態 %d のため、サブスクライバの作成に失敗しました\n", rc);
pas_shutdown(disp);
return;
}subscribe(_subscriber, "enp://yoyo.com/xyz",
_handle_notify, NULL,
_subscribe_ack, NULL);static void _unsubscribe(int sig)
{
(int)sig;
unsubscribe(_subscriber, _subscription, _unsubscribe_ack, NULL);
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];if (argc < 2) _exit_usage();
if (*(argv[1]) == '0')
{
strcpy(host, "127.0.0.1");
} else {
strcpy(host, argv[1]);
}
if (argc > 2)
{
port = (unsigned short)atoi(argv[2]);
}disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("ディスパッチャーを作成できません");subscriber_new_a(disp, NULL, host, port, _open_ack, NULL);
信頼性の高いパブリッシャとサブスクライバ
これらのコーディング例では、信頼性の高い非同期パブリッシャおよびサブスクライバを確立します。
信頼性の高いパブリッシャのサンプル
/*
* Copyright 2000 by Sun Microsystems, Inc.
* All rights reserved
*
* rpub :簡単で *信頼性の高い* 連携動作する非同期パブリッシャ
* rsub (信頼性の高いサブスクライバ) と組み合わせて
* 使用するように設計されています。
*
* 構文 :
* rpub ホスト名 ポート番号
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "publisher.h"static pas_dispatcher_t *disp = NULL;
static publisher_t *_publisher = NULL;
static int _shutdown = 0;
static renl_t *_renl;printf("\n使用法 :\nrpub ホスト名 ポート番号\n");
static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _call_shutdown()
{
_shutdown = 1;
pas_shutdown(disp);
}static void _renl_create_cb(void *arg, int rc, void *ignored)
{
(void *)arg;
(void *)ignored;if (!_publisher)
{
printf("RENL の作成に失敗しました - 状態 %d\n", rc);
_call_shutdown();
return;
}static void _publisher_new_cb(void *arg, int rc, void *enc)
{
_publisher = (publisher_t *)enc;if (!_publisher)
{
printf("パブリッシャの作成に失敗しました - 状態 %d\n", rc);
_call_shutdown();
return;
}renl_create_publisher(_publisher, "renl_id", NULL,
_renl_create_cb,NULL);static void _recv_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;if (rc < 0)
{
printf("応答のタイムアウト\n");
} else if ( rc == 0) {
printf("応答を受信しました\n");
}
fflush (stdout);static void _read_stdin()
{
static char input[1024];printf("rpub> ");
fflush(stdout);
while (!_shutdown)
{
if ( !fgets(input, sizeof(input), stdin) )
{
continue;
} else {
char *message;
unsigned int message_len;input[strlen(input) - 1] = 0; /*\n を削除する*/
if (*input == '.' && input[1] == 0)
{
publisher_delete(_publisher);
_call_shutdown();
break;
}message = strdup(input);
message_len = strlen(message);/*タイムアウト時間 5 秒*/
publish(_publisher, "enp://yoyo.com/xyz",
message, message_len,
NULL, _recv_ack, message, 5000);main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];if (argc < 2) _exit_usage();
if (*(argv[1]) == '0')
{
strcpy(host, "127.0.0.1");
} else {
strcpy(host, argv[1]);
}
if (argc > 2)
{
port = (unsigned short)atoi(argv[2]);
}disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("ディスパッチャーを作成できません");publisher_new_a(disp, NULL, host, port, _publisher_new_cb,
NULL);
信頼性の高いサブスクライバのサンプル
/*
* Copyright 1997 by Sun Microsystems, Inc.
* All rights reserved
*
* rsub :非同期サブスクライバの例
*
* 構文 :
* rsub ホスト名 ポート番号
*/#include <stdlib.h>
#include <stdio.h>#include "pasdisp.h"
#include "subscriber.h"static pas_dispatcher_t *disp = NULL;
static subscriber_t *_subscriber = NULL;
static subscription_t *_subscription = NULL;
static renl_t *_renl = NULL;static void _exit_usage()
{
printf("\n使用法 :\nrsub ホスト名 ポート番号\n");
exit(5);
}static void _exit_error(const char *msg)
{
printf("%s\n", msg);
exit(1);
}static void _subscribe_ack(void *arg, int rc, void *subscription)
{
(void)arg;if (!rc)
{
_subscription = subscription;
printf("購読依頼に成功しました\n");
_renl = renl_create_subscriber(_subscription, "renl_id", NULL);
} else {
printf("購読依頼に失敗しました - 状態 %d\n", rc)
pas_shutdown(disp);
}
}static void _unsubscribe_ack(void *arg, int rc, void *ignored)
{
(void *)ignored;
(void *)arg;if (rc != 0)
{
printf("購読の中止に失敗しました - 状態 %d\n", rc);
}subscriber_delete(_subscriber);
pas_shutdown(disp);
}static int _handle_notify(void *arg, char *url, char *str, int len)
{
(void *)arg;
printf("[%s] %.*s\n", url, len, (str) ? str : "(null)");
return 0;
}static void _open_ack(void *arg, int rc, void *enc)
{
_subscriber = (subscriber_t *)enc;(void *)arg;
if (rc)
{
printf("状態 %d のため、サブスクライバの作成に失敗しました\n", rc);
pas_shutdown(disp);
return;
}subscribe(_subscriber, "enp://yoyo.com/xyz",_handle_notify,
NULL,_subscribe_ack, NULL);static void _unsubscribe(int sig)
{
(int)sig;
unsubscribe(_subscriber, _subscription, _unsubscribe_ack, NULL);
}main(int argc, char **argv)
{
unsigned short port = 7997;
char host[256];if (argc < 2) _exit_usage();
if (*(argv[1]) == '0')
{
strcpy(host, "127.0.0.1");
} else {
strcpy(host, argv[1]);
}
if (argc > 2)
{
port = (unsigned short)atoi(argv[2]);disp = pas_dispatcher_new(NULL);
if (disp == NULL) _exit_error("ディスパッチャーを作成できません");
前へ 目次 索引 DocHome 次へ
Copyright © 2000 Sun Microsystems, Inc. Some preexisting portions Copyright © 2000 Netscape Communications Corp. All rights reserved.
Last Updated June 04, 2001