プログラム例 3: コールバックオブジェクトを利用した Hello World


クライアントプログラムでは、サーバ側で起こった変更や更新への対応が必要になることがあります。たとえば、株価サーバ上で株価が更新されるたびに、クライアントのグラフ表示プログラムやスプレッドシートプログラムでも更新を行いたいといった場合などです。このような場合、(1) 株価サーバ上のメソッドを定期的に呼び出して株価を問い合わせる、(2) 株価が更新されたらサーバから通知を受け取るようにする、という 2 つの選択肢があります。2 番目のような方法は、「コールバック」と呼ばれます。

このプログラム例 3 では、コールバックオブジェクトをクライアントプログラムからサーバに渡す方法を説明します。サーバはコールバックオブジェクト上でメソッド要求を発行するという形でクライアントに通知します。

プログラム例 3 は、コールバック機能が追加されていることを除いて、プログラム例 1 と同じです。このページでは、拡張部分のコードについてだけ説明します。

このページでは、次の内容について説明します。

このプログラム例のコンパイル方法と実行方法については、「Hello World の構築方法と実行方法」を参照してください。

インタフェース定義 (Hello.idl)

module HelloApp
{
    interface HelloCallback
    {
        void callback(in string message);
    };


    interface Hello
    {
        string sayHello(in HelloCallback objRef, in string message);
    };
};

  • クライアントで実装する HelloCallback が定義されています。

  • sayHello メソッドは、オブジェクト参照引数と文字列引数をとるように変更されています。オブジェクト参照引数は、サーバ側で起動できるコールバックオブジェクトをクライアントがサーバに渡せるようにするものです。文字列引数は、サーバがクライアントに送り返す文字列です。

    サーバの実装 (HelloServer.java)

    // Copyright and License 
    
    import HelloApp.*;
    import org.omg.CosNaming.*;
    import org.omg.CosNaming.NamingContextPackage.*;
    import org.omg.CORBA.*;
     
    class HelloServant extends _HelloImplBase 
    {
        public String sayHello(HelloCallback callobj, String msg)
        {
    	callobj.callback(msg);
    	return "\nHello world !!\n";
        }
    }
    
     
    public class HelloServer {
     
        public static void main(String args[])
        {
    	try{
    	    // create and initialize the ORB
    	    ORB orb = ORB.init(args, null);
     
    	    // create servant and register it with the ORB
    	    HelloServant helloRef = new HelloServant();
    	    orb.connect(helloRef);
     
    	    // get the root naming context
    	    org.omg.CORBA.Object objRef = 
    		orb.resolve_initial_references("NameService");
    	    NamingContext ncRef = NamingContextHelper.narrow(objRef);
     
    	    // bind the Object Reference in Naming
    	    NameComponent nc = new NameComponent("Hello", "");
    	    NameComponent path[] = {nc};
    	    ncRef.rebind(path, helloRef);
     
    	    // wait for invocations from clients
                java.lang.Object sync = new java.lang.Object();
                synchronized (sync) {
                    sync.wait();
                }
     
    	} catch (Exception e) {
    	    System.err.println("ERROR: " + e);
    	    e.printStackTrace(System.out);
    	}
        }
    }
     
  • sayHello メソッドは、受け取ったコールバックオブジェクトを起動するように変更されています。

    クライアントの実装 (HelloClient.java)

    // Copyright and License 
     
    import HelloApp.*;
    import org.omg.CosNaming.*;
    import org.omg.CORBA.*;
     
    class HelloCallbackServant extends _HelloCallbackImplBase
    {
        public void callback(String notification)
        {
            System.out.println(notification);
        }
    }
    
    public class HelloClient 
    {
        public static void main(String args[])
        {
    	try{
    	    // create and initialize the ORB
    	    ORB orb = ORB.init(args, null);
     
                // get the root naming context
                org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
                NamingContext ncRef = NamingContextHelper.narrow(objRef);
    
                // resolve the Object Reference in Naming
                NameComponent nc = new NameComponent("Hello", "");
                NameComponent path[] = {nc};
                Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
     
    	
    	    HelloCallbackServant helloCallbackRef = new HelloCallbackServant();
                orb.connect(helloCallbackRef);
    
    	    // call the Hello server object and print results
    	    String hello = helloRef.sayHello(helloCallbackRef,"\ntest..\n");
    	    System.out.println(hello);
     
    	} catch (Exception e) {
    	    System.out.println("ERROR : " + e) ;
    	    e.printStackTrace(System.out);
    	}
        }
    }
    
     
  • クライアントでは、HelloCallbackServant オブジェクトを実装しています。

  • HelloClient.main は、コールバックオブジェクトのインスタンスを生成し、それをサーバに渡します。クライアントは、コールバックオブジェクトの ORB への登録も行わなければなりません。

    Hello World の構築方法と実行方法

    以下の説明では、Java IDL ネームサーバ用にポート 1050 を使用できることを前提としています。必要であれば、別のポートに変更してください。なお、1024 以下のポートを使用する場合は、UNIX マシンであればスーパーユーザの権限が、Windows95 および NT であれば管理者の権限が必要です。また、以下の説明ではパス名でスラッシュ (/) を使用していますが、Windows95 および NT ではバックスラッシュ (\) に置き換える必要があります。


    ホーム

    Copyright © 1995-98 Sun Microsystems, Inc. All Rights Reserved.