Previous Table of Contents Next


22.11.3 Client-Side C++ Example of the Callback Model


   22.11.3.1 C++ Example of Generated ReplyHandler

   The ReplyHandler Servant class generated for the StockManager interface is:

   // Generated file: stockmgr_s.hh (Filename is non-normative)// C++ - AMI_StockManagerHandler declarationclass POA_AMI_StockManagerHandler

   : public POA_Messaging::ReplyHandler{public:// Programmer must implement the following pure virtuals:

   // Mappings for attribute handling functionsvirtual void get_stock_exchange_name(const char * ami_return_val) = 0; virtual void get_stock_exchange_name_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0;

   virtual void set_stock_exchange_name() = 0;virtual void set_stock_exchange_name_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0;

   // Mappings for the operation handling functionsvirtual void add_stock(CORBA::Boolean ami_return_val) = 0;virtual void add_stock_excep(

   Messaging::ExceptionHolder_ptr excep_holder) = 0;

   virtual void edit_stock() = 0;virtual void edit_stock_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0;

   virtual void remove_stock(CORBA::Double quote) = 0;virtual void remove_stock_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0;

   virtual void find_closest_symbol(CORBA::Boolean ami_return_val, const char * symbol) = 0;

   virtual void find_closest_symbol_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0;

   virtual void get_quote(CORBA::Double d) = 0;virtual void get_quote_excep(Messaging::ExceptionHolder_ptr excep_holder) = 0; };

   The programmer must now derive from the generated handler and implement the pure virtual methods. The following points should be considered when implementing these handler-derived reply handlers:

   22.11.3.2 C++ Example of User -Implemented ReplyHandler

   The following code is an example implementation of a user derived and implemented reply handler based on the generated reply handler from Section 22.11.3.1, “C++ Example of Generated ReplyHandler,? on page 22-31. The inherited methods, which were previously declared as pure virtual are declared here as virtual and are implemented as part of this class:

   // File: AsyncStockHandler.h// C++ - Declaration in my own header#include "stockmgr_s.hh"// Include filename non-normative

   class AsyncStockHandler : public POA_AMI_StockManagerHandler{public:AsyncStockHandler() { }virtual ~AsyncStockHandler() {}

   // Mappings for attribute handling functionsvirtual void get_stock_exchange_name(const char * ami_return_val); virtual void get_stock_exchange_name_excep(Messaging::ExceptionHolder_ptr excep_holder);

   virtual void set_stock_exchange_name();virtual void set_stock_exchange_name_excep(Messaging::ExceptionHolder_ptr excep_holder);

   // Mappings for the operation handling functionsvirtual void add_stock(CORBA::Boolean ami_return_val);virtual void add_stock_excep(

   Messaging::ExceptionHolder_ptr excep_holder);

   virtual void edit_stock();virtual void edit_stock_excep(Messaging::ExceptionHolder_ptr excep_holder);

   virtual void remove_stock(CORBA::Double quote);virtual void remove_stock_excep(Messaging::ExceptionHolder_ptr excep_holder);

   virtual void find_closest_symbol(CORBA::Boolean ami_return_val, const char * symbol);

   virtual void find_closest_symbol_excep(Messaging::ExceptionHolder_ptr excep_holder);

   virtual void get_quote(CORBA::Double d);virtual void get_quote_excep(Messaging::ExceptionHolder_ptr excep_holder); };

   Each of these callback operations have implementations as in the following. Please note that for the sake of brevity, each pointer is not checked before it is used. This is intentional.

   // AsyncStockHandler.cpp#include <AsyncStockHandler.h>

   voidAsyncStockHandler::get_stock_exchange_name(const char * ami_return_val){cout << "Exchange Name = " << ami_return_val << endl;}voidAsyncStockHandler::get_stock_exchange_name_excep(

   Messaging::ExceptionHolder_ptr excep_holder); {try {

   excep_holder->raise_exception();}catch (const CORBA::SystemException& e) {

   cout << "Get stock_exchange_name exception [" << e << "]" << endl;}}

   voidAsyncStockHandler::set_stock_exchange_name(){// No data returned since this was the "set" of the attribute.cout << "Set stock_exchange_name succeeded!" << endl;}voidAsyncStockHandler::set_stock_exchange_name_excep(

   Messaging::ExceptionHolder_ptr excep_holder) {try {

   excep_holder->raise_exception();}catch (const CORBA::SystemException& e) {

   cout << "Set stock_exchange_name exception [" << e << "]" << endl;}}

   voidAsyncStockHandler::add_stock(){// No data returned but no exception either which is good news.cout << "Stock was added!" << endl;}voidAsyncStockHandler::add_stock_excep(

   Messaging::ExceptionHolder_ptr excep_holder) {try {

   excep_holder->raise_exception();

   }

   catch (const CORBA::SystemException& e) {cout << "add_stock exception [" << e << "]" << endl;

   }

   }

   void

   AsyncStockHandler::edit_stock()

   {

   // No return data but no exception either which is good.

   cout << "Stock was edited!" << endl;

   }

   void

   AsyncStockHandler::edit_stock_excep(Messaging::ExceptionHolder_ptr excep_holder)

   {

   try {excep_holder->raise_exception();

   }

   catch (const CORBA::SystemException& e) {cout << "edit_stock System Exception exception [" << e << "]" << endl;

   }

   catch (const InvalidStock& e) {cout << "edit_stock invalid symbol [" << e.sym << "]" << endl;

   }

   }

   void

   AsyncStockHandler::remove_stock(

   CORBA::Double quote)

   {

   cout << "Stock Removed and quote = " << quote << endl;

   }

   void

   AsyncStockHandler::remove_stock_excep(Messaging::ExceptionHolder_ptr excep_holder)

   {

   try {excep_holder->raise_exception();

   }

   catch (const CORBA::SystemException& e) {cout << "remove_stock System Exception exception [" << e << "]" << endl;

   }

   catch (const InvalidStock& e) {cout << "remove_stock invalid symbol [" << e.sym << "]" << endl;

   }

   }

   voidAsyncStockHandler::find_closest_symbol(CORBA::Boolean ami_return_val,const char* symbol){

   if (ami_return_val)cout << "Closest stock = " << symbol << endl;

   elsecout << "No closest stock could be found!" << endl;

   }

   void

   AsyncStockHandler::find_closest_symbol_excep(Messaging::ExceptionHolder_ptr excep_holder)

   {

   try {excep_holder->raise_exception();

   }

   catch (const CORBA::SystemException& e) {cout << "find_closest_symbol exception [" << e << "]" << endl;

   }

   }

   void

   AsyncStockHandler::get_quote(CORBA::Double quote)

   {

   cout << "Quote = " << quote << endl;

   }

   void

   AsyncStockHandler::get_quote_excep(Messaging::ExceptionHolder_ptr excep_holder)

   {

   try {excep_holder->raise_exception();

   }

   catch (const CORBA::SystemException& e) {cout << "get_quote System Exception exception [" << e << "]" << endl;

   }

   catch (const InvalidStock& e) {cout << "get_quote invalid symbol [" << e.sym << "]" << endl;

   }

   }

   22.11.3.3 C++ Example of Callback Client Program

   The following code shows how to set QoS at the ORB and object reference scopes (the two most common levels) and make asynchronous invocations using the user-implemented reply handler from the previous section. Again, for the sake of brevity, checking for valid pointers and placing all of the CORBA calls in try blocks has been omitted.

   // callback_client_main.cpp#include <AsyncStockHandler.h>int main(int argc, char ** argv){// Initialize the ORBCORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

   // Initializing objRef for StockManager -- assumes IOR is passed

   // on command-lineCORBA::Object_var obj = orb->string_to_object(argv[1]);StockManager_var stockMgr = StockManager::_narrow(obj);

   // Obtain the ORB’s PolicyManagerCORBA::Object_var orbQosObj =

   orb->resolve_initial_references("ORBPolicyManager");CORBA::PolicyManager_var orbQos =CORBA::PolicyManager::_narrow(orbQosObj);

   // Create and apply an ORB-wide Routed Delivery QoSCORBA::Any routing_val;Messaging::RoutingTypeRange routing;routing.min = Messaging::FORWARD;routing.max = Messaging::STORE_AND_FORWARD;routing_val <<= routing;CORBA::PolicyList orb_pols(1);orb_pols.length(1);orb_pols[(CORBA::ULong) 0] = orb->create_policy(Messaging::ROUTING_POLICY_TYPE, routing_val);orbQos->set_policy_overrides(orb_pols, CORBA::ADD_OVERRIDE);

   // Create and apply an object-reference-specific Priority QoSCORBA::Any priority_val;Messaging::PriorityRange priority;priority.min = 5;priority.max = 15;priority_val <<= priority;CORBA::PolicyList obj_pols(1);obj_pols.length(1);obj_pols[(CORBA::ULong) 0] = orb->create_policy(Messaging::REQUEST_PRIORITY_POLICY_TYPE,priority_val);stockMgr = stockMgr->set_policy_overrides(obj_pols);

   // At this point QoS has been set and a protocol selected.

   // Create an async handler for each async function.// Note that the same handler instance could be used across the board // if we wanted to only create a new Object Reference for each // invocation and then correlate the timing data with each ObjectId // ourselves.//// The following code assumes implicit activation of Servants with the// RootPOAAsyncStockHandler* handlerImpls[6];for (int i = 0; i < 6; i++)

   handlerImpls[i] = new AsyncStockHandler();

   AMI_StockManagerHandler_var handlerRefs[6];for (int i=0; i < 6; i++)handlerRefs[i] = handlerImpls[i]._this();

   // Async AttributesstockMgr->sendc_set_stock_exchange_name(handlerRefs[0], "NSDQ");

   stockMgr->sendc_get_stock_exchange_name(handlerRefs[1]);// Async OperationsstockMgr->sendc_add_stock(handlerRefs[2], "ACME", 100.5);stockMgr->sendc_edit_stock(handlerRefs[3], "ACME", 150.4);

   // Notice no out param is passed.stockMgr->sendc_remove_stock(handlerRefs[4], "ABC");

   stockMgr->sendc_find_closest_symbol(handlerRefs[5], "ACMA");

   // callbacks get invoked during other distributed requests and during// eventloop processing.// Assume that done is set by handler implementation when all replies// have been received or request have timed out.while(!done)

   orb->perform_work();return 0;}