ACE+TAO Opensource Programming Notes/Advertise your service on a naming service

Discussion edit

So the previous client/server pair were a bit clunky. What they lacked in elegance, they gained in brevity. This client/server example will show how to edit the previous examples so that they use the naming service and nolonger rely on the clunky manual IOR method of addressing. As a side note, these IOR strings are only good for the length of time the server is running. Since each new process generates a unique IOR string, storing them in a file for client reuse just isn't feasible, therefore, we use the naming service, which acts like a DNS for our services.

So, to make this work, we need to get a reference to a naming service, create a name with which to bind our service under, and register that name with the naming service. The following lines of code are what we will need:

  //Now we need a reference to the naming service
  Object_var naming_context_object = orb->resolve_initial_references ("NameService");
  CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_context_object.in ());
  //Then initialize a naming context
  CosNaming::Name name (1);
  name.length (1);
  //store the name in the key field...
  name[0].id = string_dup ("widgits");
  //Then register the context with the nameing service
  naming_context->rebind (name, dc_log.in ());

Placing this code above the "orb->run" line of the previous server will get it on the naming server. For the full source code, see the following listing

main.cpp edit

So, as you can see, the main difference here is the addition of a new include for the naming service and the code snipit mentioned above. The other portions of the server remain exactly the same.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
#include "basicI.h"
#include "basicC.h"
#include "ace/streams.h"
#include <orbsvcs/CosNamingC.h>

using namespace std;
using namespace CORBA;

int main (int argc, char* argv[])
{
    // First initialize the ORB, that will remove some arguments...
    ORB_var orb = ORB_init (argc, argv, "ORB" /* the ORB name, it can be anything! */);
    Object_var poa_object = orb->resolve_initial_references ("RootPOA");
    PortableServer::POA_var poa = PortableServer::POA::_narrow (poa_object.in ());
    PortableServer::POAManager_var poa_manager = poa->the_POAManager ();
    poa_manager->activate ();

    // Create the servant
    My_Factory_i my_factory_i;

    // Activate it to obtain the object reference
    My_Factory_var my_factory = my_factory_i._this ();

    // Put the object reference as an IOR string
    String_var ior = orb->object_to_string (my_factory.in ());
    //Now we need a reference to the naming service
    Object_var naming_context_object = orb->resolve_initial_references ("NameService");
    CosNaming::NamingContext_var naming_context = CosNaming::NamingContext::_narrow (naming_context_object.in ());
    //Then initialize a naming context
    CosNaming::Name name (1);
    name.length (1);
    //store the name in the key field...
    name[0].id = string_dup ("Widgits");
    //Then register the context with the nameing service
    naming_context->rebind (name, my_factory.in ());
    //By default, the following doesn't return unless there is an error
    orb->run ();

    // Destroy the POA, waiting until the destruction terminates
    poa->destroy (1, 1);
    orb->destroy ();
    return 0;
}