1 / 18

第三章 一个最小的 CORBA 应用程序

第三章 一个最小的 CORBA 应用程序. 3.1 本章概述 本章介绍如何建立一个简单的 CORBA 应用程序,它由一个简单的服务器程序和一个能访问这个对象的客户机组成,在此将熟悉创建一个最小的应用程序都需要有那些基本不骤,另外还有一些程序员代码的解释细节。 3.2 编写和编译一个 IDL 定义。 CORBA 应用程序第一步是用 IDL 定义它的接口,下面的 IDL 中包含了一个结构定义和一个单独的接口。 struct TimeOfDay { short hour; // 0 - 23

errol
Télécharger la présentation

第三章 一个最小的 CORBA 应用程序

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第三章 一个最小的CORBA应用程序 • 3.1 本章概述 本章介绍如何建立一个简单的CORBA应用程序,它由一个简单的服务器程序和一个能访问这个对象的客户机组成,在此将熟悉创建一个最小的应用程序都需要有那些基本不骤,另外还有一些程序员代码的解释细节。 3.2 编写和编译一个IDL定义。 CORBA应用程序第一步是用IDL定义它的接口,下面的IDL中包含了一个结构定义和一个单独的接口。 struct TimeOfDay { short hour; // 0 - 23 short minute; // 0 - 59 short second; // 0 - 59 }; interface Time { TimeOfDay get_gmt(); };

  2. 第三章 一个最小的CORBA应用程序 • 接口Time定义一个传送当前时间的对象,Time对象只有一个单个的操作get_gmt。客户调用这个操作来获得当前时间。当前时间是以结构类型TimeofDay形式表示当前时间。 • 文件存成time.idl,并对其进行编译。然而不同供应商提供的ORB不同,则可能生成的文件就不同,可是基础概念对所有使用C++语言映射的对象都是一样。 • $ idl time.idl • 将生成若干新的文件。 • time.hh 这是插入在客户机程序的源代码中的头文件。它包含time.idl中用到的类型在C++类型定义。 • timeC.cc 此文件包含编译和连接客户应用程序的C++存根代码。它提供一个生成的API,客户机应用程序可以调用这个API来与在time.idl所定义的对象进行通信。

  3. 第三章 一个最小的CORBA应用程序 • timeS.hh 这是一个插入在服务器程序源代码中的头文件。它包含一些定义这些定义允许应用程序代码实现一个在time.idl中定义的对象。 • timeS.cc 这个文件包含编译和连接入服务器应用程序的C++框架。它提供这个服务器应用程序所需的运行时支持,所以它能够接收客户机程序发送的操作调用。 • 3.3 编写和编译一个服务器程序 整个服务器程序的源代码如下: #include <time.h> #include <iostream.h> #include "server.hh“ class Time_impl : public virtual POA_Time { public: virtual TimeOfDay get_gmt() throw(CORBA::SystemException); };

  4. 第三章 一个最小的CORBA应用程序 • TimeOfDay • Time_impl:: • get_gmt() throw(CORBA::SystemException) • { • time_t time_now = time(0); • struct tm * time_p = gmtime(&time_now); • TimeOfDay tod; • tod.hour = time_p->tm_hour; • tod.minute = time_p->tm_min; • tod.second = time_p->tm_sec; • return tod; • }

  5. 第三章 一个最小的CORBA应用程序 • int • main(int argc, char * argv[]) • { • try { • // Initialize orb • CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); • // Get reference to Root POA. • CORBA::Object_var obj • = orb->resolve_initial_references("RootPOA"); • PortableServer::POA_var poa • = PortableServer::POA::_narrow(obj); • // Activate POA manager • PortableServer::POAManager_var mgr • = poa->the_POAManager(); • mgr->activate();

  6. 第三章 一个最小的CORBA应用程序 • // Create an object • Time_impl time_servant; • // Write its stringified reference to stdout • Time_var tm = time_servant._this(); • CORBA::String_var str = orb->object_to_string(tm); • cout << str << endl; • // Accept requests • orb->run(); • } • catch (const CORBA::Exception &) { • cerr << "Uncaught CORBA exception" << endl; • return 1; • } • return 0; • }

  7. 第三章 一个最小的CORBA应用程序 • 此服务器实现了一个Time对象,头文件timeS.hh包含一个称为POA_Time的抽象定义。定义如下: • // In file timeS.hh • class POA_Time: • public virtual PortableServer::ServerBase{ • public: • virtual ~POA_Time(); • Time_ptr _this(); • virtual TimeofDay get_gmt() • throw(CORBA::SystemException)=0; • }; • 这个类包含一个get_gmt纯虚拟方法。为了创建一个客户机程序可以调用的实现对象,在此必须为get_gmt方法提供一个实现的POA_Time中派生一个具体类。这就是说头几行编码应该如下: #include <time.h> #include <iostream.h> #include "server.hh“ class Time_impl : public virtual POA_Time { public: virtual TimeOfDay get_gmt() throw(CORBA::SystemException);};

  8. 第三章 一个最小的CORBA应用程序 • 在此定义了从POA_Time派生来的类Time_impl。这个类提供了一个客户机真正能够与其通信的Time对象的一个具体实现。 • 下一步是Time_impl中get_gmt方法的实现。忽略出错,返回值为-1,则返回一个毫无意义的时间值,而不引发异常。 • TimeOfDay • Time_impl:: • get_gmt() throw(CORBA::SystemException) • { • time_t time_now = time(0); • struct tm * time_p = gmtime(&time_now); • TimeOfDay tod; • tod.hour = time_p->tm_hour; • tod.minute = time_p->tm_min; • tod.second = time_p->tm_sec; • return tod; • }

  9. 第三章 一个最小的CORBA应用程序 主函数 • 以上程序完成了对象的实现,下面是main函数。头几行代码对于多数服务器都一样,是对服务器端ORB的初始化。 • 下步是提供一个Time对象的实际司服程序,以便客户机发送一个调用给它。可以通过创建一个Time_impl司服类得是例来完成。 • Time_impl time_servant; //create a Time Object • 为了客户机能够访问这个对象,客户机需要一个对象引用,在此通过将它作为字符串写到stdout中来提供这个引用。 • // Write its stringified reference to stdout • Time_var tm = time_servant._this(); • CORBA::String_var str = orb->object_to_string(tm); • cout << str << endl;

  10. 第三章 一个最小的CORBA应用程序 • 对_this的调用创建了这个对象的对象引用。 • 有了一个Time对象的具体实现,客户程序就可以引用它,现在,服务器就可以接受请求了,在运行时,通过调用run来指示ORB做些什么。 • orb->run(); //接收请求 • Run方法开始进入时间循环,等待有客户机程序发出的请求。 • 剩下的代码为一个异常处理程序,它输出一个错误消息并终止main。 • } • catch (const CORBA::Exception &) { • cerr << "Uncaught CORBA exception" << endl; • return 1; • } • return 0; • } • 完成以上任务后,就可编译和连接服务器程序代码。 • $ CC –c –I/opt/myORB/include timeC.cc • $ CC –c –I/opt/myORB/include times.cc • $ CC –c –I/opt/myORB/include myserver.cc

  11. 第三章 一个最小的CORBA应用程序 • 如果没有错误,将产生三个可以连接成一个可执行程序的对象文件。 • $ CC –O myserver timeC.o timeS.o myserver.o\ • >-L/opt/myORB/lib –lorb • 假设ORB运行库为liborb。这样就可运行此程序。运行后,服务器程序在stdout上输出一个引用给它的Time对象,然后,一直等待客户请求。客户机发信号给它,它才终止。 • 3.4 编写和编译一个客户程序 • 客户机的源代码如下: #include <iostream.h> #include <iomanip.h> #include "time.hh" //----------------------------------------------------------------------------- int main(int argc, char * argv[]) {

  12. 第三章 一个最小的CORBA应用程序 try { // Check arguments if (argc != 2) { cerr << "Usage: client IOR_string" << endl; throw 0; } // Initialize orb CORBA::ORB_var orb = CORBA::ORB_init(argc, argv); // Destringify argv[1] CORBA::Object_var obj = orb->string_to_object(argv[1]); if (CORBA::is_nil(obj)) { cerr << "Nil Time reference" << endl; throw 0; } // Narrow Time_var tm = Time::_narrow(obj); if (CORBA::is_nil(tm)) { cerr << "Argument is not a Time reference" << endl; throw 0; }

  13. 第三章 一个最小的CORBA应用程序 // Get time TimeOfDay tod = tm->get_gmt(); cout << "Time in Greenwich is " << setw(2) << setfill('0') << tod.hour << ":" << setw(2) << setfill('0') << tod.minute << ":" << setw(2) << setfill('0') << tod.second << endl; } catch (const CORBA::Exception &) { cerr << "Uncaught CORBA exception" << endl; return 1; } catch (...) { return 1; } return 0; }

  14. 第三章 一个最小的CORBA应用程序 • 必须包含一个客户端的头文件time.hh,以便IDL定义能用于客户机应用程序代码,先做了个参数检验,并用ORB_init来初始化ORB的运行状态。 #include <iostream.h> #include <iomanip.h> #include "time.hh“ int main(int argc, char * argv[]) { try { // Check arguments if (argc != 2) { cerr << "Usage: client IOR_string" << endl; throw 0; } // Initialize orb CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

  15. 第三章 一个最小的CORBA应用程序 • 发送了一个零来实现一个简单的出错处理形式,在main函数的结尾处的异常处理程序保证了如果出现任何问题错误,客户机将以非零状态退出。 • 接下来几行代码将命令参数(一个对对象Time的字符串化引用)转换成一个对象引用: // Destringify argv[1] CORBA::Object_var obj = orb->string_to_object(argv[1]); if (CORBA::is_nil(obj)) { cerr << "Nil Time reference" << endl; throw 0; } 这样就形成了一个object类型的对象引用。但客户程序根据这个引用能够调用一个操作之前,它必须将引用强制转换为正确的类型,即Time。 // Narrow Time_var tm = Time::_narrow(obj); if (CORBA::is_nil(tm)) { cerr << "Argument is not a Time reference" << endl; throw 0; }

  16. 第三章 一个最小的CORBA应用程序 • 对Time_narrow的调用起着一个强制动态类型的转换(dynamic cast)相同的目的,它测试一个引用是否是指定类型。如果是,_narrow返回一个非零引用,否则位零引用。 • 现在,这个对象程序已拥有在服务器上被激活的Time对象的对象引用,用这个对象引用可以获得当前时间值: // Get time TimeOfDay tod = tm->get_gmt(); cout << "Time in Greenwich is " << setw(2) << setfill('0') << tod.hour << ":" << setw(2) << setfill('0') << tod.minute << ":" << setw(2) << setfill('0') << tod.second << endl; 对get_gmt的调用将激活在服务器中对get_gmt方法远程过程调用,这个调用一直到服务器返回当前时间值是才阻塞,客户程序在stuout输出这个结果。 整个过程与服务器位于什么位置毫无关系。ORB将负责Time对象的定位,并调用这个请求给对象,整个过程是透明的。 客户程序的命令部分是由两个异常处理组成,处理出错。

  17. 第三章 一个最小的CORBA应用程序 • 以上步骤完成后,便可对其进行编译和连接: $ CC –c –I/opt/myORB/include timeC.cc $ CC –c –I/opt/myORB/include myclient.cc $ CC –O myclient timeC.o myclient.o\ >-L/opt/myORB/lib –lorb 假如没错误,将产生一个myclient客户即可执行的程序 • 3.5 运行客户机和服务器程序 先运行服务器,应将服务器程序输出的对象引用字符串重定向到一个文件中,以便将它传递给客户机程序的命令行。为了在服务器程序运行时,继续使用终端,将服务器程序放在后台执行。 在服务器程序运行后,启动客户程序,将由服务器在命令行输出的那个对象引用传递给它,客户程序根据传给的引用读入当前时间值,并且在它推出前将时间值输出到stdout。最后,通过发送一个SIGTERM给它来终止这个服务器程序。

  18. 第三章 一个最小的CORBA应用程序 • $ ./myserver>tmp/myserver.ref & • [1] 7898 • $ ./myclient ‘cat/tmp/myserver.ref’ • Time in Greenwich is 23:47:56 • $ kill %1 • [1] + Terminated ./myserver & • $ • 建立一个完整的应用程序需要涉及四个步骤: • 1. 定义IDL • 2. 编译IDL • 3. 编写和编译服务器程序 • 3. 编写和编译客户程序 • 如果服务器程序是现成的,你只要编写一个与服务器程序通信的客户程序就可以了。因此第1步和第三步就不用了。

More Related