用TAO创建股票报价系统
Building a Stock Quoter with TAO- A Tutorial
本教程译自$(ACE_ROOT%)/TAO/ docs/tutorials/Quoter。由Stone Jiang试译。原文
revision history:
date: 2007-11-05 by Stone Jiang
本教程是围绕一个单一的应用程序组织的,它允许客户端程序可以通过报价服务获取股票报价。该应用程序是基于Doug Schmidt和Steve Vinoski为C++ Report杂志的对象互联专栏的序列文章而开发的。
这篇教程从简单的客户程序及服务程序到剖析TAO的高级特性而逐步构建,这些高级特性包括了:asynchronous method invocation,reliable oneways, real-time Evnet Service, Interoperable Naming Service等等。
在您阅读本教程时,您可以自由地从提供的链接处获取到源文件。但是,如果您选择了编译和运行示例程序,这些源文件是作为您下载的TAO源文件的一部分。您可以从这下目录
$TAO_ROOT/docs/tutorials/Quoter
找到源代码,里面还包含了编译时需要的Makefile文件。由于本在线教有可能使用了与您不同版本的ACE+TAO源代码,因此单独下载这些源代码可能不能正确编译。
- 介绍- 一个很简单的客户端
- 介绍-一个很简单的服务端
- 介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID
- 介绍-改进服务端,通过POA策略之持久化对象引用
- 实现仓库
- TAO的命名服务
- 异步方法调用-CORBA为没有耐心的客户端提供的解决方案
- 按需激活
- TAO的Cos事件服务
- TAO的RT事件服务
- RTCORBA
1.介绍—— 一个很简单的客户端
我们将从一个相当简单的IDL接口开始我们的教程:我们想要创建一个股票报价服务,可以通过某些接口查询股票的价格。为了使学习之旅更加有趣,我们将用不同的CORBA对象表示不同的股票。哦,这看上去有些夸张,但是这些趣味性会激发我们更多的学习欲望,尤其在学习开始的时候。
定义IDL接口
对于股票报价系统,最起码的操当属查询股票价格的操作了,表示如下:
interface Stock
{
double price();
};
但通常,股票有符号和全称,于是我们再增加两个属性来便于查询:
interface Stock
{
double price();
readonly attribute string symbol;
readonly attribute string full_name;
};
我们还需要某个接口,通过它可以根据股票的符号访问它的对象引用。习惯上,我们把这种接口称其为工厂(Factory),它看上去像这样:
interface Stock_Factory
{
Stock get_stock (in string stock_symbole);
};
请注意参数怎样具有方向性的:方向性用in,out, inout表示。仅输入用(in)表示,仅输出用(out)表示,既输入也输出用(inout)表示。到这里我们还有一个问题,如果股票的符号无效会怎么办呢?CORBA的做法是抛出一个异常:
exception Invalid_Stock_Symbol{};
我们再把异常作为Stock_Factory接口的一部分:
interface Stock_Factory
{
Stock get_stock (in string stock_symbole)
raise (Invalid_Stock_Symbol);
};
最后,我们把上面所有的IDL组织在一起并放进一个模块中以避免对名字空间的污染,于是得到了Quoter.idl 文件。
//filename: Quoter.idl
module Quoter
{
exception Invalid_Stock_Symbol {};
// Used to report an invalid stock name
// Forward declare the Stock interface
interface Stock;
interface Stock_Factory
{
// = TITLE
// A factory class for the stock quoter interfaces
//
// = DESCRIPTION
// Return the Quoter interfaces based on their names
//
Stock get_stock (in string stock_symbol)
raises (Invalid_Stock_Symbol);
};
interface Stock
{
// = TITLE
// A simple interface to query the name and price of stock
//
// = DESCRIPTION
// Return the price and name of a single stock
//
readonly attribute string symbol;
// Get the stock symbol.
readonly attribute string full_name;
// Get the name.
double price ();
// Get the price
};
};
生成的文件
让我们花几分钟来查看生成的代码。你无须经常这样做,事实上你根本无须这样做。但是我们这样做是为了学习的需要,并帮助您打消对IDL编译器的神密感。
为了生成代码,你必须调用IDL编译器,操作如下:
$ACE_ROOT/TAO/TAO_IDL/tao_idl Quoter.idl。
在Windows下,tao_idl.exe在%ACE_ROOT%/bin中。
%ACE_ROOT%/bin/tao_idl Quoter.idl
如果把%ACE_ROOT%/bin 添加至环境变量PATH中,则可以简化为
tao_idl Quoter.idl
IDL编译器完整的文档和选项都包含在compiler.html 中。
TAO为每个IDL文件生成9个文件。
QuoterC.h, QuoterC.inl 和 QuoterC.cpp 包含了客户端的接口。注意,内联(inline)函数放在独立的文件中,这样你可以有选择的编译它们,以便生成更小的代码。单纯的客户端只需要链接从QuoterC.cpp生成的目标文件。
与之相似,
QuoterS.h, QuoterS.inl 和 QuoterS.cpp 包含了服务端的skeletons。服务端必须链接从QuoterS.cpp和QuoterC.cpp生成的目标文件。
最后,
QuoterT.h, QuoterT.inl 和 QuoterT.cpp 包含TIE类。有基于组合的方式代替基于继承的skeleton标准(在CORBA 2.2规范之后)。把它们分离在不同的文件中仅仅是因为有的编译器不能处理中同一个源代码文件中同时混合了模板和非模板的代码。因此你根据不需要在所有平台上编译这些文件。然后,编译QuoterS.cpp需要这些文件。还要注意的事,如果您的平台不支持命字空间,那么对于有的IDL接口不能使用TIE方法。
上面提到的扩展名和后缀可以通过使用IDL编译器的选择来修改,要知道更多的细节,可以查阅文档。另外还需要注意的事情是您需要在您的项目中使用一致的扩展名,否则在你的IDL源文件中使用某些#include指令时会出现问题。
创建一个简单的客户端
在IDL接口就绪之后,我们想要编写简单的客户端了。在所有的CORBA客户端或服务端要做的第一件事就是初始化ORB:
int main( int argc, char* argv[])
{
try {
// First initialize the ORB, that will remove some arguments…
CORBA::ORB_var orb =
CORBA::ORB_init(argc, argv,
"" /* the ORB name, it can be anything! */
);
IDL支持在编译时长度未知的变长类型,因此在运行时需要动态分配它们。_var 类型减化了我们对变长类型显示内存管理,还隐藏了定长和变长结构化的类型之间的区别。
ORB初始化可能失败,实际上,所有的CORBA操作都可能抛出CORBA::SystemException 异常,我们用 try/catch语句块来检查可能的失败。 不用说,这是非常天真的;某些失败是临时的,我们需要更好的方法从错误中恢复,但在我们的示例中这已经足够了。因此,在main()函数的最后,我们捕获了CORBA的所有类型的异常。
}
catch (CORBA::Exception &ex)
{
std::cerr << "CORBA exception raised!" << std::endl;
}
return 0;
}
我们不能忘记ORB是一种资源,应用程序必须释放它。直到CORBA 2.3,并没有标准的方法来处理释放ORB这件中。TAO已经采纳了新的规范,于是,我们的客户程序将如下所示:
int main (int argc, char* argv[])
{
try {
// First initialize the ORB, that will remove some arguments...
CORBA::ORB_var orb =
CORBA::ORB_init (argc, argv,
"" /* the ORB name, it can be anything! */);
// the real code goes here!
orb->destroy ();
}
catch (CORBA::Exception &ex) {
std::cerr << "CORBA exception raised!" << std::endl;
}
return 0;
}
关于ORB名字,仅需要几句话来说明:如果在CORBA::init中使用了相同的ORB标识,规范要求ORB返回相同的ORB指针,并且,即使使用了不同的标识,返回相同指针的实现也是自由的。通常这不是问题,这是由于大多数应用程序只实例化单一的ORB。TAO是实际支持多个ORB指针中少数CORBA实现之一。这一点对于real-time应用程序非常重要,在这些应用程序里,每一个ORB可以在与不同的优先级执行。
既然我们已经拥有了ORB指针,我们可以启动此应用程序了。正常情况下,我们使用Naming Service, Trading Service或者Interoperable Naming Service来定位股票工厂,但这里为了简化起见,让我们在第一个参数中使用IOR字符串。
最简单的方法是用第一个参数来得到字符串,然后用string_to_object()函数把它转换成对象引用。
CORBA::Object_var factory_object =
orb->string_to_object (argv[1]);
Quoter::Stock_Factory_var factory =
Quoter::Stock_Factory::_narrow (factory_object.in ());
_narrow()函数用于测试一个引用是否为指定的类型。如果引用是指定的类型,它返回一个非空的引用,否则返回为空。
关于TAO有些有趣的事情:第一,对于对象引用,它支持file:scheme,因此,第一个参数可以是file://a_file_name. 在这种情形下,ORB将打开名为"a_file_name"的文件并从文件中读取IOR。TAO还支持corbaloc:scheme,例如
corbaloc:iiop:1.1@ace.cs.wustl.edu:12345/Stock_Factory。
因此使用字符串可能是非常强大的引导协议。
如果我们要使用从IDL编译器生成的接口,那就就必须包含正确的头文件。
#include "QuoterC.h"
注意,这是您仅需要包含的头一个文件; IDL 编译器生成的代码包含了所有需要的内部头文件。当我们使用TAO服务时,也不要忘了包含那些适当的头文件。
TAO另一个有趣的特性是它支持 _unchecked_narrow()。 这是CORBA Messaging规范的一部分,在本质上它与_narrow()执行同样的工作,但不同的时,它并不远程的检查类型。如果你在编译时有必要的信息能确定narrow操作的正确性,那么使用不检查的版本会更高效。
现在我们可以使用剩余的参数来找回股票对象:
for (int i = 2; i != argc; ++i) {
try {
// Get the stock object
Quoter::Stock_var stock =
factory->get_stock (argv[i]);
练习1
完成客户端的实现。这一点应该很容易,但是它给了你机会来建立你的开发环境并能让你熟悉构建TAO应用程序的基础知识。
解决方案
查看 client.cpp文件;和你的代码比应该没有多少不同。在你的客户端代码、idl文件和QuoterC.*文件中分别数一下代码的行数,你会想再一次重写所有的代码吗?
测试
若要测试本程序,我们还需要服务端能工作,这是我们进入本教程下一课最好的理由。
分享到:
相关推荐
本教程将深入讲解如何利用TAO来创建一个股票报价系统,这对于理解TAO和CORBA的工作原理以及在实际项目中的应用具有很高的参考价值。 首先,我们需要了解TAO的基本概念。TAO作为一个ORB(对象请求代理),它是CORBA...
- **7.7 性能影响**:评估使用TAO::Transport::Current对系统性能的影响。 - **7.8 示例代码**:提供具体的代码示例来演示TAO::Transport::Current的使用方法。 #### 八、安全性 - **8.1 使用SSLIOP**:指导如何...
在编程领域,TAO(Test and Automation Objects)是一个重要的框架,主要用于自动化测试和系统集成。它提供了一种结构化的、可扩展的方式来设计和实现复杂的测试用例和自动化流程。这篇入门教程是为那些初涉TAO编程...
【标题】"适用于分布式实时系统的Cobra Tao"揭示了该技术是针对实时系统设计的,主要基于ACE(Adaptive Communication Environment)框架,并结合了COBRA(CORBA Component Model)服务器,即TAO(The Adaptive ...
The Tao of Network Security Monitoring Beyond Intrusion Detection By Richard Bejtlich Pages : 832 英文
**TAO (The ACE ORB)** 是一个著名的开源免费CORBA(Common Object Request Broker Architecture)实现,广泛应用于分布式系统的开发中。本篇文章将根据提供的文档标题、描述、标签以及部分内容,深入解析与TAO相关...
2. **TAO**作为CORBA的一种实现,是一个用C++编写的高性能实时ORB,支持多种操作系统,包括Win32和Unix/Linux等实时操作系统。TAO提供了丰富的服务,能够满足各种分布式系统的需求。 **二、基本概念** 1. **Client...
通过以上内容可以看出,《TAO Programmer's Guide》是一份全面且详细的文档,不仅覆盖了从基础知识到高级主题的所有方面,还提供了丰富的实例和指南,非常适合希望使用 TAO 和 ACE 构建分布式系统的开发人员。
为了帮助开发者快速上手,TAO提供了“Hello World”示例,该示例展示了如何使用TAO创建一个简单的分布式应用程序。步骤包括定义IDL文件、实现服务器端和客户端、编译并运行应用程序。 #### 六、IDL编译器及其特性 ...
在C#中利用Tao Framework进行OpenGL建模的关键步骤之一是创建OpenGL设备环境。这涉及到使用`contextGL`类,它定义了控制OpenGL环境的命令,如像素格式、调色板的创建等。一旦设备环境被成功创建,就可以开始设置...
OCI公司提供对TAO的技术支持,包括一本名为《TAO Developer's Guide》的详细指南,尽管价格不菲,但这本书对于深入理解TAO的使用非常有帮助。此外,OCI还有自己的TAO发行版,可以关注其FAQ和Mailing List以获取更多...
再者,Tao.Platform.Windows则是针对Windows操作系统的一系列实用工具和API接口的封装,它为开发者提供了与Windows系统进行深度交互的能力。通过这个组件,开发者可以轻松访问系统资源,如文件系统、注册表,甚至...
它通过一系列创新性的设计和技术选择,在保证系统可用性和效率的同时,实现了对大量社交数据的有效管理和访问。对于那些需要处理海量数据并提供快速响应的服务来说,TAO提供了宝贵的经验和参考价值。
- **协议策略**:针对实时系统的特殊需求,定义了一系列协议策略以提高性能和可靠性。 - **TAO支持**:详细介绍了TAO在实时系统中的支持情况,包括QoS服务质量保证。 ##### 8. 压缩 - **使用压缩**:提供了简单易用...
ACE(Adaptive Communication Environment)和TAO(The ACE ORB)是两个开源的软件框架,主要应用于分布式系统和网络通信。ACE提供了一组C++库,用于构建高性能、跨平台的应用程序,而TAO是基于ACE的一个ORB(Object...
在VS2008中新建一个C++项目,然后在源代码中导入TAO的头文件,并使用ORB(Object Request Broker)接口来创建和激活对象。一个基本的示例可能包括定义一个接口(IDL文件),生成对应的C++代码,然后创建ORB、注册...
1. **表结构**:在"tao_data.sql"中,我们预期会看到一系列CREATE TABLE语句,定义了数据库中的各个表格,如用户表(user)、商品表(product)、订单表(order)等。这些表格通过字段(column)来存储数据,每个...
【标题】"TAO的一个小hello" 是一个基于TAO(The ACE ORB)实现的CORBA(Common Object Request Broker Architecture)示例程序。TAO是ACE(Adaptive Communication Environment)的一部分,它是一个跨平台的、开源...
### 使用ACE/TAO开发企业级应用 #### ACE与TAO简介 ACE(Adaptive Communication Environment,自适配通信环境)是一种开源框架,为开发者提供了众多用于构建高性能、分布式的实时系统以及嵌入式系统的组件和模式...