`
pleasetojava
  • 浏览: 729593 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

TAO教程之十:TAO的实时事件服务

阅读更多

TAO的实时事件服务

我们已探研了如何使用TAO的COS事件服务来接收更新过的股票的价格,但是如果我们并不关心所有的股票又怎么样呢?一个方法是使用多个事件通道,每个通道承载不同的消息容量。例如,每个事件通道仅携带股票其中的一部分。在本节中,我们将探讨另一个广案,即使用TAO实事事件服务来为我们执行过滤。TAO的实时事件服务可做许多其它事情,像保存具有优先级的点对点,使用多播来节省网络资源,产生超时和间隔的事件,以及它可以与TAO的调度服务协作用于分析您系统的可调度性。

取回股价的变化

在本例中,我们将会使用我们前一章用过的相同的数据结构,也就是事件将是相同的。TAO的实时事件服务可被配置用于以类型安全的方式携带事件,或你可以使用自定义的编码来发送非在事件中非IDL结构体,但第一点它可以像COS 事件服务一样简单的使用。

作为消费者连接

作为消费者连接是很相似的。一些基类和签名变化了,但它基本上具有相同的思想:先让我们定义消费者对象:

class Stock_Consumer : public POA_RtecEventComm::PushConsumer {
public:
  Stock_Consumer ();

  void push (const RtecEventComm::EventSet& data);
  void disconnect_push_consumer (void);

  // details omitted
};

注意的是我们接收一个事件集合代替单个事件。事件通道可以使用这个特征来把多个事件放入队列和把它们放进一个单个操作。首先我们需要从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

注意事件有多个结构,它们有区分明显的事件头和事件数据体,并且事件数据体比一个any还多。事件头用于提供过滤,事件数据体字段可配置为在编译时携带无论哪种您想要的IDL结构体。现在我们可以输出新的股票价格了:

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

我们也必须实现断开连接的回调:

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

As with the COS Event Channel we can voluntarily disconnect, too:

与COS 事件通道一样我们也可以自愿断开连接。

void
Stock_Consumer::disconnect ()
{
  // Do not receive any more events...
  this->supplier_proxy_->disconnect_push_supplier ();
}
如何连接到实时事件通道

连接到实时事件通道与连接到正规的事件通道非常的相似。只有一点不同,就是我们必须指定为想要接收的事件。这一点使用相当复杂的IDL结构来描述,但是TAO提供了一个帮助类来生产它。我们将假定我们使用命名服务或其它相似的服务来获取一个事件服务的引用:

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

现在我们用事件通道来获取消费都连接使用的工厂:

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

再用工厂找回代理:

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

现在我们列出我们想接收的事件。我们用简单的算法来给事件类型赋给每支股票:

    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');

然后我们创建订阅:

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

和连接到代理:

    RtecEventComm::PushConsumer_var myself = this->_this ();
    this->supplier_proxy_->connect_push_consumer (
        myself.in (),
        subscriptions.get_ConsumerQOS ());
}
通知股价的变化

As with the COS Event Channel example we will make our implementation of the Modify_Stock interface generate events whenever the price changes:

与COS事件通道示例一样无论什么时候只要股价变化我们都将创建Modify_Stock接口的实现来创建事件。

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_;
};

set_price()方法的实现非常相似。第一我们存储新的价格:

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

下一步我们准备事件。这时我们必须创建一个序列,但我们仅有在里面有一个元素:

   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;

在本示例中没有使用事件源,但它必须是非0的。现在我们可以设置事件数据体:

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

and send the event to the event channel:

  this->consumer_proxy_->push (event);
}
作为提供者连接到事件服务

作为在COS事件通道的情形下,我们需要提一个供者特征与它连接。我们获得事件服务的访问方法,例如使用命名服务:

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

接下来我们用事件通到来获得提供者连接使用的工厂:

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

和用工厂获得一个代理:

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

我们构建发布器因此事件通可以在基于他们通用的事件之的消费者和提供者之间进行匹配:

   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);

最后我们连接到消费者代理上:

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

最后我们实现断开连接的回调:

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

实现接收股价更新事件的消费者,

已提供了头文件 header file , 一起的还有client.cpp. 还提供了这些文件Quoter.idl, Makefile, Stock_i.h, Stock_i.cpp, Stock_Factory_i.h, Stock_Factory_i.cpp, 和server.cpp.

解决方案

用您的方案与 Stock_Consumer.cpp比较。

测试

要测试您的变化您需要运行三个程序,先要运行TAO的命名服务:

$ $TAO_ROOT/orbsvcs/Naming_Service/Naming_Service

然后运行TAO的实时事件服务

$ $TAO_ROOT/orbsvcs/Event_Service/Event_Service

再运行您的客户端:

$ client AAAA CCCC

最后运行服务端:

$ server MSFT BBBB CCCC < stock_list.txt

Here is the stock_list.txt file.

Exercise 2

向上面那样配置,但是这次运行多个客户端和服务端:

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

客户端能接收来来自两个服务端的所有事件吗?

这是 stock_list1.txtstock_list2.txt 文件。

分享到:
评论

相关推荐

    TAO程序员指南(入门教程)

    TAO的架构基于服务导向的设计,包括事件服务、定时器服务、命名服务等。这些服务为测试用例提供了基础设施,使开发者可以专注于编写业务逻辑,而不是底层通信细节。 4. **TAO的测试组件** - **测试用例管理器**:...

    适用于分布式实时系统的Cobra Tao

    【标题】"适用于分布式实时系统的Cobra Tao"揭示了该技术是针对实时系统设计的,主要基于ACE(Adaptive Communication Environment)框架,并结合了COBRA(CORBA Component Model)服务器,即TAO(The Adaptive ...

    TAO CORBA CPP 编程指南 C++

    2. **TAO**作为CORBA的一种实现,是一个用C++编写的高性能实时ORB,支持多种操作系统,包括Win32和Unix/Linux等实时操作系统。TAO提供了丰富的服务,能够满足各种分布式系统的需求。 **二、基本概念** 1. **Client...

    TAO Programmers Guide.pdf

    - **Using the TAO::Transport::Current Feature**(使用TAO::Transport::Current特性):第48页开始,介绍了该特性的作用域、上下文、配置等方面的信息。 - **Security**(安全):第57页开始,提供了关于使用SSL ...

    catior.rar_TAO_tao catior

    【标签】"tao tao_catior" 这两个标签明确了压缩包的主要内容是关于 TAO 技术以及与之关联的 "tao_catior" 工具。TAO 是一个测试框架,它允许在各种编程语言和平台上编写可互操作的测试代码。"tao_catior" 可能是 ...

    基于TAO的CORBA编程详细介绍.rar

    "5_Hello World - 简单实例"是每个编程教程的传统起点,通过一个简单的程序展示了如何使用TAO实现CORBA的客户端和服务端通信。这个例子有助于初学者快速理解CORBA的基本工作流程。 **6. 使用命名服务** "6_Naming ...

    用TAO创建股票报价系统实例讲解

    4. **事件服务(Event Service)**:如果系统需要支持推送模式,即服务器主动向客户端发送更新,那么可以利用TAO的事件服务。股票价格变动时,服务器可以发布事件,客户端订阅后会接收到通知。 5. **异常处理**:在...

    TAO编程指南.doc

    - **TAO (The ACE ORB)**: 是基于C++的一种高性能、可扩展的实时CORBA平台。由美国华盛顿大学的Douglas C. Schmidt教授领导开发,遵循CORBA 2.6规范。TAO作为一个开源项目,为开发者提供了强大的工具和库来构建复杂...

    TAO Programming Guide

    此外,文档也提供了对TAO::Transport::Current特性的使用说明,这个特性可以使得程序员在特定的上下文中访问传输对象的当前状态和功能。 在安全性方面,文档介绍了如何使用SSLIOP(SSL Internet Inter-ORB Protocol...

    ACE.rar_ACE_TAO

    TAO完全遵循CORBA标准,提供了完整的ORB实现,包括GIOP/IIOP协议栈、ORB核心、对象适配器、类型编码、持久化服务等。TAO的设计考虑了性能和可伸缩性,使其成为高性能分布式系统开发的理想选择。 压缩包中的“ACE-...

    Matlab7.0教程和例题

    这个名为“Matlab7.0教程和例题”的压缩包显然旨在为初学者提供一个全面的学习资源,帮助他们掌握MATLAB的基本操作和应用。下面将详细讨论MATLAB的基础知识以及可能在例题中涉及到的关键概念。 首先,MATLAB的基础...

    CORBA Quick Start-Using TAO with C++Builder 6

    ### 相关知识点 ...通过以上知识点的学习,开发者可以快速掌握如何使用C++Builder 6结合TAO进行CORBA应用的开发,包括创建项目、编写IDL文件、编写客户端和服务端代码以及构建和安装ACE+TAO等关键环节。

    WAPPush.rar_TAO_WML_push_wap push_wappush.rar

    标签"tao wml push wap_push wappush.rar"进一步细化了主题,"wml push"指的是使用WML语言实现的推送服务,而"wap_push"和"wappush.rar"则直接指代WAP Push技术和与之相关的资源文件。 压缩包内的文件名为"WAPPush....

    使用Tao和C#进行OpenGL 3D导航

    在提供的压缩包文件中,"OpenGL-3D-Navigation-with-Tao-and-C.pdf"可能是关于这个主题的教程文档,详细解释了如何使用Tao和C#实现3D导航。"OpenGLNavigationWithTaoCSharpSource.zip"可能包含示例代码,你可以从中...

    OpenDDS安装教程 Java开发

    2. 编译ACE_TAO:编译ACE_TAO的步骤与编译ACE相同, 只需要更换目录和名称即可。 3. 编译OPENDDS:使用命令行工具,cd到OpenDDS的目录下,执行命令,检查opendds根目录中是否生成了DDS_no_tests.sln文件和setenv....

    yuenan2tao_kingviewsoftware_kingview_tranningkingview_programkin

    在"yuenan2tao"这个文件名中,虽然没有明确的关键词,但我们可以推测这可能是一个用户的个人标识,或者代表了一次特定的培训课程或教程资源。 学习Program Kingview,不仅需要掌握软件的基本操作,还要理解工业自动...

    基于deepstream-python yolov8的车辆识别检测模型.完整代码详细教程

    完整代码详细教程"涵盖了利用NVIDIA DeepStream SDK结合Yolov8模型进行实时车辆检测的整个流程,包括模型的加载、配置文件的编写、推理的执行以及结果的处理和展示。这个教程对于希望利用GPU加速计算机视觉应用的...

    ACE指南 ACE程序员教程 ACE论文集 ACE应用实例

    ACE实现了一系列核心功能,以满足高性能和实时通信服务及应用的需求。这些功能主要包括: - **事件多路分离和事件处理器分派**:使程序能够同时处理多个事件,提高应用程序的响应速度和处理能力。 - **信号处理**:...

    VxWorks-开发简明培训教程Manual.pdf

    《VxWorks开发简明培训教程》是一份旨在帮助用户理解和掌握VxWorks实时操作系统以及在PowerPC上进行开发的教程。本教程的作者朱海涛假设读者已经具备基本的Windows操作经验和之前参加过的相关培训基础。对于未参加过...

    ACE自适配通信环境中文技术文档

    ACE提供了一组丰富的可复用C++ Wrapper Facade(包装外观)和框架组件,可跨越多种平台完成通用的通信软件任务,其中包括:事件多路分离和事件处理器分派、信号处理、服务初始化、进程间通信、共享内存管理、消息...

Global site tag (gtag.js) - Google Analytics