Keywords: doc

Next: Implementation Overview Up: Separating client and server Previous: Naming Service

### The MICO Binder (CORBA Extension)

There is still one problem left: How do you get an object reference for the naming service itself? Especially if the naming service and the client reside on machines that do not share a file system that could be used to pass around stringified object references as in the previous section. Because the CORBA standard does not offer a solution to this problem MICO has to invent its own. Because it might be useful for other purposes as well we decided to make the solution available to you, dear user. Note that using this feature makes your programs incompatible with other CORBA implementations.

The MICO Binder is a very simple naming service that maps (Address, RepositoryId) pairs to object references. A RepositoryId is a string that identifies a CORBA IDL-object and consists of the absolute name of the IDL-object and a version number. RepositoryId's are generated by the IDL compiler. The RepositoryId for the `Account` interface looks like this:

      IDL:Account:1.0

See section [6.6] of [5] for details on RepositoryId's. An Address identifies one process on one computer. MICO currently defines three kinds of addresses: internet addresses, unix addresses, and local addresses. An internet address is a string with the format

      inet:<host name>:<port number>

which refers to the process on machine `<host name>` that owns the TCP port `<port number>`. Unix addresses look like

      unix:<socket file name>

and refer to the process on the current machine that owns the unix-domain socket bound to `<socket file name>`. Local addresses look like

      local:

and refer to the process they are used in (i.e., this process). Here is an adaption of the account example which uses the MICO binder:

     1: // file account_server2.cc
     2:
     3: #include "account.h"
     4:
     5: class Account_impl : virtual public Account_skel
     6: {
     7:   // unchanged, see section "MICO Application"
     8:   // ...
     9: };
    10:
    11:
    12: int main( int argc, char *argv[] )
    13: {
    14:   // ORB initialization
    15:   CORBA::ORB_var orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );
    16:   CORBA::BOA_var boa = orb->BOA_init( argc, argv, "mico-local-boa" );
    17:
    18:   Account_impl* server = new Account_impl;
    19:
    20:   boa->impl_is_ready( CORBA::ImplementationDef::_nil() );
    21:   orb->run ();
    22:   CORBA::release( server );
    23:   return 0;
    24: }

The server is essentially the same as in 3.3.3 except that it does not write a stringified object reference to a file. Here is the client:

     1: // file account_client2.cc
     2:
     3: #include "account.h"
     4:
     5:
     6: int main( int argc, char *argv[] )
     7: {
     8:   // ORB initialization
     9:   CORBA::ORB_var orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );
    10:   CORBA::BOA_var boa = orb->BOA_init( argc, argv, "mico-local-boa" );
    11:
    12:   CORBA::Object_var obj
    13:     = orb->bind ("IDL:Account:1.0", "inet:localhost:8888");
    14:   if (CORBA::is_nil (obj)) {
    15:      // no such object found ...
    16:   }
    17:   Account_var client = Account::_narrow( obj );
    18:
    19:   client->deposit( 700 );
    20:   client->withdraw( 250 );
    21:   cout << "Balance is " << client->balance() << endl;
    22:
    23:   return 0;
    24: }

After completing ORB and BOA initialization the client uses `bind()` to bind to an object with repository id `IDL:Account:1.0` that is running in the process that owns port 8888 on the same machine. Lines 14-16 check if the bind failed. Everything else is the same as in section 3.3.3. Compile:

      mico-c++ -I. -c account.cc -o account.o
      mico-c++ -I. -c account_server2.cc -o account_server2.o
      mico-c++ -I. -c account_client2.cc -o account_client2.o
      mico-ld -o server2 account.o account_server2.o -lmico2.2.3
      mico-ld -o client2 account.o account_client2.o -lmico2.2.3

Start the server like this, telling it to run on port number 8888:

      ./server2 -ORBIIOPAddr inet:localhost:8888

Run the client in a different shell without any arguments. It should behave the same way as the client from section 3.3.3.

If a server offers several objects (lets say `A` and `B`) of the same type (i.e., with the same repository id) and a client wants to bind to `A` it needs a means to distinguish objects of the same type. This is accomplished by assigning objects an identifier during creation in the server and specifying this identifier as an extra argument to `bind()` in the client. The identifier is of type `BOA::ReferenceData`, which is a sequence of octets. You can use `ORB::string_to_tag()` and `ORB::tag_to_string()` to convert a string into such an identifier and vice versa. Here are the changes to the server code:

     1: #include "account.h"
     2:
     3: class Account_impl : virtual public Account_skel {
     4: public:
     5:  Account_impl (const CORBA::BOA::ReferenceData &refdata)
     6:     : Account_skel (refdata)
     7:   {
     8:     _current_balance = 0;
     9:   }
    10:   // remaining parts unchanged
    11: };
    12:
    13: int main( int argc, char *argv[] )
    14: {
    15:   ...
    16:   CORBA::BOA::ReferenceData_var id
    17:     = CORBA::ORB::string_to_tag ("foo");
    18:   Account_impl* server = new Account_impl (id);
    19:   ...
    20: }

Changes to the client:

     1: #include "account.h"
     2:
     3: int main( int argc, char *argv[] )
     4: {
     5:   ...
     6:   CORBA::BOA::ReferenceData_var id
     7:     = CORBA::ORB::string_to_tag ("foo");
     8:   CORBA::Object_var obj
     9:     = orb->bind ("IDL:Account:1.0", id, "inet:localhost:8888");
    10:   ...
    11: }

To avoid hardcoding the address of the server into the client you can leave out the second argument to `bind()` and specify a list of addresses to try using the `-ORBBindAddr` command line option. For example

      ./client -ORBBindAddr local: -ORBBindAddr inet:localhost:8888

will make `bind()` try to bind to an account object in the same process and if that fails it will try to bind to an account object running in the server than owns port 8888 on the same machine. Note that addresses specified using `-ORBBindAddr` are only taken into account if you to not specify an explicit address.

The `demo/account2` directory contains an example that uses the MICO binder.

Next: Implementation Overview Up: Separating client and server Previous: Naming Service