ACE+TAO Opensource Programming Notes/Create an event consumer

Discussion

edit

This event client is designed to accept the events from the previously defined event server. The main difference between the server, where you can simply stuff some message in a CORBA::Any object and sent it to the event dispatcher, the client needs to overload the POA_CosEventComm::PushConsumer class. Specifically, the push and disconnect members need to be overridden.

main.cpp

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

#include <iostream>
#include <cstdlib>
#include "eventsinkC.h"
#include "eventsinkconsumer_i.h"

using namespace std;

//#include "acbc.h"

int main(int argc, char *argv[])
{
  // Initialize the ORB.
  CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "whatever");
   
  CORBA::Object_var poa_object = orb->resolve_initial_references ("RootPOA");
  //Now we need a reference to the naming service
  CORBA::Object_var naming_context_object = orb->resolve_initial_references ("NameService");
  CosNaming::NamingContext_var naming_context = 
      CosNaming::NamingContext::_narrow (naming_context_object.in ());
  
  CosNaming::Name ec_name;
  ec_name.length(1);
  ec_name[0].id = CORBA::string_dup("CosEventService"); //TAO Specific

    // Resolve the binding to the event channel object reference.
  CosEventChannelAdmin::EventChannel_var channel = CosEventChannelAdmin::EventChannel::_narrow(naming_context->resolve(ec_name));
//      resolve_name<CosEventChannelAdmin::EventChannel>(
//      naming_context, ec_name);
  //Instanciate the servant
  EventSinkConsumer_i servant(orb.in());
  
  //Register it with the root POA
  naming_context_object = orb->resolve_initial_references("RootPOA");
  PortableServer::POA_var poa = PortableServer::POA::_narrow(naming_context_object.in());
  PortableServer::ObjectId_var oid = poa->activate_object(&servant);
  CORBA::Object_var consumer_obj = poa->id_to_reference(oid.in());
  CosEventComm::PushConsumer_var consumer = CosEventComm::PushConsumer::_narrow(consumer_obj.in());
  
  //Get a consumer admin object for the event channel
  CosEventChannelAdmin::ConsumerAdmin_var consumerAdmin = channel->for_consumers();
  
  //Get a proxy supplier from the consumer admin
  CosEventChannelAdmin::ProxyPushSupplier_var supplier = consumerAdmin->obtain_push_supplier();
  
  //Connect to the proxy push supplier, passing the push consumer object ref to it
  supplier->connect_push_consumer(consumer.in());
  
  //Activate the POA via its POAManager
  PortableServer::POAManager_var poa_manager = poa->the_POAManager();
  poa_manager->activate();
  cout << "Starting to receive events" << endl;
  
  //Start the event loop
  orb->run();
  orb->destroy();
  
  return EXIT_SUCCESS;
}

eventsinkconsumer_i.h

edit
#ifndef EVENTSINKCONSUMER_I_H
#define EVENTSINKCONSUMER_I_H

#include <iostream>
#include "eventsinkC.h"
#include "eventsinkI.h"

/**
The class responsible for specializing the POA_CosEventComm::PushConsumer interface

	@author Evan Carew <Carew@pobox.com>
*/
class EventSinkConsumer_i : public virtual POA_CosEventComm::PushConsumer
{
  CORBA::ORB_var orb_;
public:
  EventSinkConsumer_i(CORBA::ORB_ptr orb);
  virtual void push( const CORBA::Any &data) throw(CORBA::SystemException);
  virtual void disconnect_push_consumer() throw(CORBA::SystemException);
};

#endif

eventsinkconsumer_i.cpp

edit
#include "eventsinkconsumer_i.h"

using namespace std;

/** \fn EventSinkConsumer_i::EventSinkConsumer_i(CORBA::ORB_ptr orb)
 * Just make a copy of the orb pointer in the constructor.
 */
EventSinkConsumer_i::EventSinkConsumer_i(CORBA::ORB_ptr orb)
  : orb_(CORBA::ORB::_duplicate(orb))
{}

/** \fn EventSinkConsumer_i::push( const CORBA::Any &data)
 * Override the push op
 */
void EventSinkConsumer_i::push( const CORBA::Any &data) throw(CORBA::SystemException){
  //Extract the event data from the Any 
  accepted *bill_event;
  if(data >>= bill_event)
    cout << "Bill Event Data: Bill = " << bill_event->bill << " Status = " << 
	bill_event->status << " Command = " << bill_event->command << endl;
}

/** \fn EventSinkConsumer_i::disconnect_push_consumer()
 * Override the disconnect operation
 */
void EventSinkConsumer_i::disconnect_push_consumer() throw(CORBA::SystemException){
  //Deactivate this object 
  CORBA::Object_var obj = orb_->resolve_initial_references("djb");
  PortableServer::Current_var current = PortableServer::Current::_narrow(obj.in());
  PortableServer::POA_var poa = current->get_POA();
  PortableServer::ObjectId_var objectId = current->get_object_id();
  poa->deactivate_object(objectId.in());
}

eventsink.idl

edit

Actually, this is a copy of eventsource.idl.

 struct accepted{
  unsigned long bill;
  unsigned long status;
  unsigned long command;
 };
edit

-lTAO_CosEvent_Skel -lTAO_CosEvent -lTAO_PortableServer -lTAO_CosNaming -lTAO_AnyTypeCode -lTAO -lACE