Object Rquest Broker

第0.43版 2016年10月23日
第0.13版 1999年 5月 4日

概要

メモリマッピングオブジェクトとウィンドウメッセージを使って
プロセス間でリモートプロシージャコールを行うサンプルです。
メモリマッピングオブジェクトとウィンドウメッセージの部分を
Socketを使ったものに書き換え、ネーミングサーバを用意すれば
CORBAやJava-RMIと同等のことができるようにもなります。

サンプル

bank/1/*
クライアントサーバ型でクライアントの要求をサーバが処理し
結果をクライアントに返すサンプルです。
下記の前準備をした後、AccoutClient.bat を実行するとサンプルが起動します。

bank/2/*
ひとつのクライアントの処理要求をサーバが処理し
サーバでの処理結果を複数のクライアントに通知するサンプルです。
下記の前準備をした後、AccoutClient.bat を実行するとサンプルが起動します。
両者とも、預金口座があって、預け入れと引き出しができる簡単なものです。

前準備

Altairのサンプルの前準備で、 ライブラリgbgp.albが作成されていることを確認してください。

bank/1/altair.ini, bank/2/altair.ini中の
LIBDIR, END_LIBDIRで囲まれたところにある"C:/Altair/Data"という
ディレクトリ記述をgbgp.albが置かれているディレクトリに書き換えてください。

altair.exe, alcore1.dllにPATHを通してください。

bank/1/bus.prop, bank/2/bus.propに
共通サービスおよびサーバの自動起動の設定がされていますが
これはこのままでOKです。

サンプルの構造

インターフェース
    Account.alb

クライアントAP
    accountstub.alb        メソッド呼び出しのスタブ
    orbgbgp.apr            GUIを含むAPの構築環境
    accountClient.gpr      GUIを持つクライアントAP

サーバAP
    accountskelton.alb     メソッド呼び出しのスケルトン
    accountserver.apr      サーバAP

共通ライブラリ
    orb.alb

共通ライブラリの主なAPI

class ORB
public: static list start_deamon();
    // 共通サービスのスタート
public: static list end_deamon();
    // 共通サービスの終了

public: static list init(string title);
    // クライアントおよびサーバの初期化

public: static ObjRef obj_to_ref(ORB_Object obj);
    // オブジェクトをオブジェクト参照にする
public: static ORB_Object ref_to_obj(ObjRef ref);
    // オブジェクト参照をオブジェクトにする

public: static list bind(ORB_Object obj, string name);
    // オブジェクトを名前をつけて共通サービスに登録および登録解除
public: static ObjRef resolve(string name);
    // 共通サービスで名前からオブジェクト参照を取り出す

public: static ReqResult request(ObjRef ref, string method, list arg_dcl, list arg_list);
    // リモートメソッド呼び出し
public: static list want_notify(ORB_Object obj, string event, list remove);
    // 通知して欲しいイベントの登録および登録削除
public: static list notify(string event, list arg);
    // イベントの発行

サンプルコード

○インターフェース
public: integer balance;
public: integer diposit(integer amount);
public: integer withdraw(integer amount);

○スケルトン
public: integer AccountSkelton::diposit(integer amount)
{
    if (amount < 0) {
        return "負の金額は預け入れられません";
    } else {
    }
    if (amount > 1000000) {
        return "百万円より多い金額は預け入れられません";
    } else {
    }
    if (balance + amount > 10000000) {
        return "預金総額が千万円を超えます";
    } else {
    }
    balance = balance + amount;
    return balance;
}

○サーバAP
{
    var list err;
    if (err = ORB::init("server")) {
        al_print("ORBの初期化に失敗しました。\n");
        return;
    } else {
    }
    var AccountSkelton account;
    account = new AccountSkelton;
    account.create();
    if (err = ORB::bind(account, "Bank")) {
        al_print("オブジェクトのバインドに失敗しました。\n");
        return;
    } else {
    }
}

○スタブ
public: integer AccountStub::diposit(integer amount)
{
    var string method;
    var list arg_dcl, arg_list;
    method = al_gp("method_name", null, null, null, null);
    arg_dcl = al_gp("arg_dcl", null, null, null, null);
    arg_list = al_gp("arg_list", null, null, null, null);
    var ReqResult result;
    result = ORB::request(ref, method, arg_dcl, arg_list);
    if (result.exception) {
        return result.exception;
    } else {
    }
    return result.ret_val;
}

○クライアントAP
--- 初期化
{
    var integer err;
    if (err = ORB::init("client")) {
        al_print("ORBの初期化に失敗しました。\n");
        return;
    } else {
    }
    var ObjRef ref;
    if (ref = ORB::resolve("Bank")) {
    } else {
        al_print("名前 Bank のオブジェクト参照取得に失敗しました。\n");
        return;
    }
    var AccountStub stub;
    stub = new AccountStub;
    stub.ref = ref;
    account = stub;
}
--- 預け入れ
{
    var integer amount, balance;
    amount = (integer)diposit_edit.text;
    diposit_edit.text = "";
    withdraw_edit.text = "";
    balance = account.diposit(amount);
    balance_label.text = (string)balance;
    diposit_edit.Damage();
    withdraw_edit.Damage();
    balance_label.Damage();
}

○共通サービスおよびサーバの自動起動の設定ファイル内容
begin_broker
	command:	"altair -file orb.apr -class ORB -method start_deamon"
	directory:	"."
	show:		true
	timeout:	10
end_broker

begin_tool
	name:		"Bank"
	command:	"altair -file accountserver.apr -class AccountServer -method main"
	directory:	"."
	show:		true
	timeout:	10
end_tool

end


メッセージシーケンスチャート


【Bind】
                               Broker                   Server
  start broker if necessary
                                 |      (CreateProcess)    |
                                 |<------------------------|
                                 |     broker_mapfile      |
                                 |create                   |
                                 |----->|                  |
                                 |      |       (wait for broker_mapfile)

                                 |                         |   mapfile
                                 |                         |create
                                 |                         |----->|
                                 |        BIND(Send)       |      |
                                 |<------------------------|close |
                                 |                         |----->|
【Resolve】

    Client                     Broker
  start broker if necessary
      |        (CreateProcess)         broker_mapfile
      |------------------------->|create
      |                          |------>|
      |(wait for broker_mapfile) |       |


      |  mapfile1                |
      |create|                   |
      |----->|   RESOLVE(Post)   |
      |------------------------->|
      |◎1                       |

  start up server if necessary
                                                        Server
      |      |                   |     (CreateProcess)
      |      |                   |------------------------>|
      |      |                   |        BIND             |
      |      |                   |<------------------------|

      |      |                   |  mapfile2
      |      |                   |create|
      |         RESOLVED(Post)   |----->|
      |<-------------------------|      |
      |      |  RESOLVE_ACK(Post)|○2   |
      |------------------------->|      |
      |close |                   |close |
      |----->|                   |----->|

【Method Call】

    Client                     Broker                    Server
      |   mapfile1               |                         |
      |create|                   |                         |
      |----->|                   |                         |
      |      |  R_C_TO_B(Post)   |                         |
      |------------------------->|   R_B_TO_S(Post)        |
      |◎1   |                   |------------------------>|
      |      |                   |                         ■   mapfile2
      |      |                   |                         |create
      |      |                   |   R_S_TO_B(Post)        |----->|
      |      |  R_B_TO_C(Post)   |<------------------------|      |
      |<-------------------------|                      ○2|      |
      |      |  R_ACK_TO_B(Post) |                         |      |
      |------------------------->|   R_ACK_TO_S(Post)      |      |
      |close |                   |------------------------>|close |
      |----->|                   |                         |----->|

【Want Notify】

                               Broker                   Consumer
                                 |                         |   mapfile
                                 |                         |create
                                 |                         |----->|
                                 |   WANT_N(Send)          |      |
                                 |<------------------------|close |
                                 |                         |----->|

【Notify】

    Supplier                   Broker                   Consumer
      |   mapfile                |                         |
      |create|                   |                         |
      |----->|  N_C_TO_B(Post)   |                         |
      |------------------------->|                         |
      |◎    |                   |   N_B_TO_S(Send)        | +
      |      |                   |------------------------>| |repeated
      |      |                   |           (Reply)       | |
      |      |                   |<------------------------| +
      |      |  N_ACK_TO_C(Post) |                         |
      |<-------------------------|                         |
      |close |                   |                         ■
      |----->|                   |                         |

If All of Servers and Consumers closes, Broker closes itself