ACE+TAO Opensource Programming Notes/Create a server
Preface
[edit | edit source]This section describes how to create a simple server similar to the quoter example in the TAO examples (ACE_wrappers/TAO/examples/Quoter).
To get this to work, create the IDL file and run the tao_idl executable on that file. The command line looks like the following:
tao_idl -GI basic.idl
This generates a whole host of source files, only one or two of which you will be required to edit.
Source File main.cpp
[edit | edit source]#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <cstdlib>
#include "basicI.h"
#include "basicC.h"
#include "ace/streams.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());
// Print it out!
//Note: You will be using this reference in the client to get it to connect to this server
//Don't even bother copying it down, it changes with each invocation & is as long as your arm
cout << ior.in() << endl;
//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;
}
Source file basic.idl
[edit | edit source]Running the tao_idl program against the following source, generates all the files you'll need to generate a simple server. The actual command line should be 'tao_idl -GI basic.idl' The command line option '-GI' is to generate the server related interface file listed below. All you need to do is to implement this file (i.e. fill out some of the empty member functions) and you're off to the races.
// Forward declare
interface Widget;
interface My_Factory
{
// = TITLE
// A factory class for the widget interfaces
//
// = DESCRIPTION
// Return the Quoter interfaces based on their names
//
Widget get_widget (in string widget_name);
};
interface Widget
{
// = TITLE
// A simple interface to query the name and price of a widget
//
// = DESCRIPTION
// Return the price and name of a single widget
//
readonly attribute string full_name;
// Get the name.
double price ();
// Get the price
};
Generated Server Interface Source
[edit | edit source]Don't forget to implement the server's interface (basicI.cpp). I usually make this a trivial call out to some other class where all the fun stuff is.
#include "basicI.h"
// Implementation skeleton constructor
My_Factory_i::My_Factory_i (void)
{
}
// Implementation skeleton destructor
My_Factory_i::~My_Factory_i (void)
{
}
::Widget_ptr My_Factory_i::get_widget (
const char * widget_name
)
ACE_THROW_SPEC ((
::CORBA::SystemException
))
{
// Add your implementation here
}
// Implementation skeleton constructor
Widget_i::Widget_i (void)
{
}
// Implementation skeleton destructor
Widget_i::~Widget_i (void)
{
}
char * Widget_i::full_name (
)
ACE_THROW_SPEC ((
::CORBA::SystemException
))
{
return "Some widget name";
}
::CORBA::Double Widget_i::price (
)
ACE_THROW_SPEC ((
::CORBA::SystemException
))
{
return 1.25;
}