跳轉到內容

ACE+TAO 開源程式設計筆記/建立事件提供者

來自華夏公益教科書

設計兩個事件端中較容易的一端是提供者。在 TAO 1.5 中,有幾個事件示例。我最喜歡的是 TAO 網站上的 COSEC,它類似於 TAO 開發者指南中的示例。不幸的是,在 TAO 網站上的示例中沒有註釋。以下是傳送每 6 秒一個事件的簡單事件提供者示例。為了實現這一點,設定了一個 ACE 計時器(帶有關聯的處理程式/回撥),它用於在指定時間傳送事件。最後,計時器被插入到一個 ACE 反應器中,並被告知以開環模式“執行”。

在閱讀程式碼時,請注意 main 頂部連線到 orb、命名服務和事件服務的方式。然後,可以找到大量與建立到事件服務的連線相關的樣板程式碼。此樣板程式碼的最後一行確定事件通道將不會關心消費者斷開連線。

/************************************************
 * 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;
}

#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

[編輯 | 編輯原始碼]
/************************************************
 * 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

[編輯 | 編輯原始碼]
  struct accepted{
    unsigned long bill;
    unsigned long status;
    unsigned long command;
  };
[編輯 | 編輯原始碼]

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

華夏公益教科書