ACE+TAO Opensource Programming Notes/Create an event consumer

From Wikibooks, open books for an open world
Jump to navigation Jump to search

Discussion[edit | edit source]

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 | edit source]

#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 | edit source]

#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 | edit source]

#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 | edit source]

Actually, this is a copy of eventsource.idl.

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

Link Line Details[edit | edit source]

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