next up previous
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 sectiongif. 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 socketgif 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 up previous
Next: Implementation Overview Up: Separating client and server Previous: Naming Service

MICO
Tue Nov 10 11:04:45 CET 1998