Jump to content

ACE+TAO Opensource Programming Notes/Create an event supplier

From Wikibooks, open books for an open world

Discussion

[edit | edit source]

The easiest of the two event sides to design is the supplier. In TAO 1.5 there are a few event examples. My favorite is the COSEC on the TAO site, which is similar to the example in the TAO Developer's Guide example. Unfortunately, in the examples on the TAO site, there are no comments. What follows is an example of a simple event supplier which sends an event every 6 seconds. To accomplish this, an ACE timer is set up (with associated handler/callback) which serves to send the event at the appointed time. Finally, the timer is inserted into an ACE reactor and told to "run" in open loop mode.

When reading the code, note at the top of main that connections are made to the orb, the naming service, and the event service. Then, quite a bit of boilerplate code related to creating connections to the event service can be found. The last line of this boilerplate code determines that the event channel will not care that consumers are disconnecting.

main.cpp

[edit | edit source]
/************************************************
 * EventSource
 * 
 * A test program for snding events over TAO's event service
 */

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

#include <iostream>
#include <cstdlib>
#include "eventsourceI.h"
#include "eventsourceC.h"
#include "etimer.h"
#include <ace/Reactor.h>
#include <orbsvcs/CosNamingC.h>
#include <orbsvcs/CosEventCommS.h>
#include <orbsvcs/CosEventChannelAdminC.h>

using namespace std;
using namespace CORBA;
CosEventChannelAdmin::ProxyPushConsumer_var consumer;

int main(int argc, char *argv[])
{
 // Initialize the ORB.
  ORB_var orb = ORB_init(argc, argv, "whatever");
   
  Object_var poa_object = orb->resolve_initial_references ("RootPOA");
  //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 ());
  
  CosNaming::Name ec_name;
  ec_name.length(1);
  ec_name[0].id = 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);
  
  // Get the admin object to the event channel 
  CosEventChannelAdmin::SupplierAdmin_var supplier_admin =
      channel->for_suppliers();
  
  // Obtain a ProxyPushConsumer from the SupplierAdmin.
  consumer =  supplier_admin->obtain_push_consumer();
  
  // Invoke the connect_push_supplier operation, passing
// a nil PushSupplier reference to it.
  CosEventComm::PushSupplier_var nil_supplier =
      CosEventComm::PushSupplier::_nil();
  consumer->connect_push_supplier(nil_supplier);
  
  MyTimer *mt = new MyTimer();
  ACE_Time_Value initialDelay (3);
  ACE_Time_Value interval (6);
  ACE_Reactor reactor;
  reactor.schedule_timer (mt, 0, initialDelay, interval);
  reactor.run_reactor_event_loop();
  
  while(1){
    cout << "In while loop." << endl;
    sleep(100);
  }
  
  orb->destroy ();
  return EXIT_SUCCESS;
}

etimer.h

[edit | edit source]
#ifndef MYTIMER_H
#define MYTIMER_H
#include <ace/streams.h>
#include <orbsvcs/CosNamingC.h>
#include <orbsvcs/CosEventCommS.h>
#include <orbsvcs/CosEventChannelAdminC.h>
#include "eventsourceC.h"
/**
Simple ACE timer impl for polling the bill acceptor & handling events

	@author Evan Carew <carew@pobox.com>
 */
class MyTimer: public ACE_Event_Handler{
  public:
    int handle_timeout(const ACE_Time_Value &, const void * = 0);
};

#endif

etimer.cpp

[edit | edit source]
/************************************************
 * EventSource
 * 
 * A test program for snding events over TAO's event service
 */
#include "etimer.h"
#include "eventsourceC.h"
using namespace std;
using namespace CORBA;

extern CosEventChannelAdmin::ProxyPushConsumer_var consumer;

/*!
    \fn MyTimer::handle_timeout(const ACE_Time_Value &, const void * = 0)
 */
int MyTimer::handle_timeout(const ACE_Time_Value &current_time, const void *nuts)
{
  //create an event
  accepted accept_event;
  accept_event.bill = 1;
  accept_event.status = 1;
  accept_event.command = 0;

  //Insert the event data into an any. 
  Any any;
  any <<= accept_event;
  
  //Now, push the event to the proxy (consumer)
  consumer->push(any);
  cout << "Pushing event." << endl;
}

eventsource.idl

[edit | edit source]
  struct accepted{
    unsigned long bill;
    unsigned long status;
    unsigned long command;
  };
[edit | edit source]

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