Tao tutorial 10: Real-time event service of Tao

Source: Internet
Author: User

Real-time event service of Tao

We have explored how to use the COs Event Service of Tao to receive the prices of updated stocks. But what if we don't care about all the stocks? One method is to use multiple event channels, each of which carries different message capacities. For example, each event Channel carries only part of the stock. In this section, we will explore another broad case, that is, using the Tao event service to filter our operations. Tao's real-time event service can do many other things, such as saving point-to-point with priority, using multicast to save network resources and generate timeout and interval events, it can also work with Tao's scheduling service to analyze the schedulability of your system.

Retrieve stock price changes

In this example, we will use the same data structure we used in the previous chapter, that is, the events will be the same. The real-time event service of Tao can be configured to carry events in a type-safe manner, or you can use custom encoding to send non-IDL structs in events, but first, it can be used as easily as the COs event service.

Connect as a consumer

As a consumer, the connection is very similar. Some base classes and signatures have changed, but they basically share the same idea: Let's first define the consumer object:

class Stock_Consumer : public POA_RtecEventComm::PushConsumer {public:  Stock_Consumer ();  void push (const RtecEventComm::EventSet& data);  void disconnect_push_consumer (void);  // details omitted};

Note that we receive an event set instead of a single event. Event channels can use this feature to put multiple events into a queue and put them into a single operation. First, we need to extract event data from any:

Void

Stock_consumer: Push (const rteceventcomm: eventset & Data)

{

For (CORBA: ulong I = 0; I! = Data. Length (); ++ I ){

Rteceventcomm: Event & E = data [I];

Quoter: Event * event;

If (E. Data. any_value >>= event) = 0)

Continue; // invalid event

Note that events have multiple structures. They have clearly distinguished event headers and event data bodies, and there are more event data bodies than any. The event header is used to provide filtering. The event data body field can be configured to carry whatever IDL struct you want during compilation. Now we can output a new stock price:

  std::cout << "The new price for one stock in /""            << event->full_name.in ()            << "/" (" << event->symbol.in ()            << ") is " << event->price << std::endl;}

We must also implement the disconnect callback:

voidStock_Consumer::disconnect_push_consumer (void){  this->supplier_proxy_ = CosEventChannelAdmin::ProxyPushSupplier::_nil ();}

As with the COs event channel we can voluntarily disconnect, too:

Like the COs event channel, We can voluntarily disconnect the connection.

voidStock_Consumer::disconnect (){  // Do not receive any more events...  this->supplier_proxy_->disconnect_push_supplier ();}
How to connect to the real-time event Channel

The connection to the real-time event channel is very similar to that to the formal event channel. The only difference is that we must specify the event to receive. This is described using a rather complex IDL structure, but Tao provides a help class to produce it. We will assume that we use the Naming Service or other similar services to obtain a reference to an event service:

    CORBA::Object_var tmp = naming_context->resolve (name);    RtecEventChannelAdmin::EventChannel_var event_channel =      RtecEventChannelAdmin::EventChannel::_narrow (tmp);

Now we use the event channel to obtain the factories used for consumption connections:

    RtecEventChannelAdmin::ConsumerAdmin_var consumer_admin =      event_channel->for_consumers ();

Use the factory retrieval Proxy:

voidStock_Consumer::connect (RtecEventChannelAdmin::ConsumerAdmin_ptr consumer_admin){    this->supplier_proxy_ =      consumer_admin->obtain_push_supplier ();

Now let's list the events we want to receive. We use a simple algorithm to assign the event type to each stock:

    CORBA::ULong rhat_event_type =      (int('R') << 24) | (int('H') << 16) | (int('A') << 8) | int('T');    CORBA::ULong aaaa_event_type =      (int('A') << 24) | (int('A') << 16) | (int('A') << 8) | int('A');

Then we create a subscription:

    ACE_ConsumerQOS_Factory subscriptions;    subscriptions.insert_type (rhat_event_type, 0);    subscriptions.insert_type (aaaa_event_type, 0);

And connect to the Proxy:

    RtecEventComm::PushConsumer_var myself = this->_this ();    this->supplier_proxy_->connect_push_consumer (        myself.in (),        subscriptions.get_ConsumerQOS ());}
Notify stock price changes

As with the COs event channel example we will make our implementation ofModify_StockInterface generate events whenever the price changes:

Similar to the COs event channel example, we will create the modify_stock interface whenever the stock price changes.

class Quoter_Modify_Stock_i : public POA_Quoter::Modify_Stock {public:  Quoter_Modify_Stock_i (const char *symbol,                         const char *full_name,                         CORBA::Double price);  void set_price (CORBA::Double new_price);  void disconnect_push_supplier (void);private:  Quoter::Event data_;  RtecEventChannelAdmin::ProxyPushConsumer_var consumer_proxy_;  POA_RtecEventComm::PushSupplier_tie < Quoter_Stock_i > supplier_personality_;};

The implementation of the set_price () method is very similar. First, we store new prices:

voidQuoter_Stock_i::set_price (CORBA::Double new_price){   this->data_.price = new_price;

Next we prepare the event. At this time, we must create a sequence, but we only have one element in it:

   RtecEventComm::EventSet event (1);   event.length (1);

We set the event type based on the stock symbol:

   RtecEventComm::Event &e = event[0];   const char *symbol = this->data_.symbol;   e.header.type =      ((int(symbol[0]) << 24)       | (int(symbol[1]) << 16)       | (int(symbol[2]) << 8)       | int(symbol[3]));  e.header.source = 1;

The event source is not used in this example, but it must be non-zero. Now we can set the event data body:

   e.data.any_value <<= this->data_;

And send the event to the event channel:

  this->consumer_proxy_->push (event);}
Connect to Event Service as a provider

As a cos event channel, we need to propose a donor feature to connect to it. We get the access method of the event service, for example, using the Naming Service:

    CORBA::Object_var tmp = naming_context->resolve (name);    RtecEventChannelAdmin::EventChannel_var event_channel =      RtecEventChannelAdmin::EventChannel::_narrow (tmp);

Next we will use the event to get the factory used for provider connection:

    RtecEventChannelAdmin::SupplierAdmin_var supplier_admin =      event_channel->for_suppliers ();

And use the factory to get a proxy:

    this->consumer_proxy_ =      supplier_admin->obtain_push_consumer ();

We build publishers so that events can be matched between consumers and providers based on common events:

   const char *symbol = this->data_.symbol;   CORBA::ULong type =      ((int(symbol[0]) << 24)       | (int(symbol[1]) << 16)       | (int(symbol[2]) << 8)       | int(symbol[3]));   CORBA::ULong source = 1;   ACE_SupplierQOS_Factory publications;   publications.insert_type (type, source, 0, 1);

Finally, we connect to the consumer agent:

    RtecEventComm::PushSupplier_var supplier =      this->supplier_personality_._this ();    this->consumer_proxy_->connect_push_supplier (supplier);

Finally, we implement the disconnect callback:

voidQuoter_Stock_i::disconnect_push_supplier (void){  // Forget about the consumer it is not there anymore  this->consumer_proxy_ =    RtecEventChannelAdmin::ProxyPushConsumer::_nil ();}
Exercise 1

Consumers who receive stock price updates,

Header file is provided, along with client. cpp. quoter. IDL, makefile, stock_ I .h, stock_ I .cpp, stock_factory_ I .h, stock_factory_ I .cpp, and server. cpp.

Solution

Compare your scheme with stock_consumer.cpp.

Test

To test your changes, you need to run the following three programs:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service

Then run Tao's real-time event service

$ $TAO_ROOT/orbsvcs/Event_Service/Event_Service

Run your client again:

$ client AAAA 

Finally run the server:

$ server MSFT BBBB < stock_list.txt

Here is the stock_list.txt file.

Exercise 2

Configure as shown above, but this time multiple clients and servers are running:

$ client AAAA MSFT$ client PPPP$ server AAAA < stock_list1.txt$ server QQQQ < stock_list2.txt

Can the client receive all events from two servers?

This is the stock_list1.txt and stock_list2.txt files.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.