2. 分布式对象计算
2.1 CORBA简介
CORBA: 由对象管理组织(OMG)提出. CORBA是一个分布式对象技术的规范,它是针对多种对象系统在分布式计算环境中如何以对象方式集成而提出的。它为对象管理定义了一个对象模型及其框架(OMA)。该模型及其框架将面向对象技术与Client/Server计算模式结合起来,有效地解决了对象封装和分布式计算环境中资源共享、代码可重用、可移植以及应用间的互操作性。
OMA参考模型:
- 应用接口: 由销售商提供的,可控制其接口的产品,相当于传统的应用表示。
- CORBA领域接口: 为特定应用领域的应用制定的规范。
- CORBA公共设施: 为终端用户提供的一组在大多数应用领域都共有的共享服务接口,它们提供可直接为业务对象使用的服务,规定业务对象有效协作所需的协定规则。
- 对象请求代理ORB: ORB是CORBA的核心. 它提供了对象请求与回答的通信机制,使得对象可以透明地发出请求和接收响应。
- CORBA对象服务: 为使用和实现对象而提供的独立与应用领域的基本服务集合。在CORBA的技术领域中,是以各种不同的软件元素来提供一个分布式应用系统所需要的各种功能的,这些软件元素在CORBA之中便称为“服务(Service)”。在CORBA的功能规格中OMG定义了许多不同目的的Service,每一个Service都有不同的功能。
CORBA服务内容:
- 对象命名服务: 每个对象有唯一的引用标识符, 可以将多个名字同一个引用相联系.
- 事件服务: 事件服务提供了分布式对象之间标准的通信机制.
- 对象安全性服务: 负责系统本身的安全性管理.
- 并发控制服务: 负责实现多客户访问情况下的并发控制和对共享资源的管理.
- 生命周期服务: 定义和描述了创建、删除、拷贝和移动对象的方法.
2.2 CORBA的基本结构
ORB接口结构图:
ORB通过接口定义语言(IDL, Interface Definition Language)程序框架或者动态程序框架来定位响应的代码实现、传送参数以及对对象实现的传送控制.
ORB的作用:
- 接受客户发出的服务请求,完成请求在服务对象段的映射
- 自动设定路由寻找服务对象
- 提交客户参数
- 携带服务对象计算结果返回客户端
IDL: IDL是用来描述产生对象调用请求的客户对象和服务对象之间的接口语言. IDL文件描述了服务器提供的服务功能, 客户机根据该接口文件描述的方法想服务器提出业务请求.
IDL词法规则: IDL采用ASCII字符集构成接口定义的所有标识符. 第一个字符必须是字母, 不区分大小写. 注释方式与C++相同.
47个保留关键字如下
IDL数据类型:
- 基本数据类型: short、long和对应的无符号类型
- 浮点数类型: float、double和long double
- 字符和超大字符: char和wchar
- 逻辑类型: boolean(true/flase)
- 八进制类型: octet定义
- any数据类型: 用于表示任意数据类型
IDL常量: 用const声明一个常量
IDL构造数据类型:
- 结构类型
struct{
long number;
string name;
};
struct foo{
long value;
sequence<foo> chain;
};
- 联合类型
union stockIn switch(short){
case 1: stocker : long;
case 2: name : string;
};
- 枚举类型
enum who{employee, visitor, others};
IDL数组类型: 与C语言类似
IDL模板类型:
序列类型
typedef sequence <long, 80> my_bounded_sequence;
typedef sequence <long> my_sequence;
字符串序列
typedef string <50> my_bounded_string;
typedef string my_string;
typedef wstring m_wide_string;
IDL接口:
接口用interface声明, 其中包含的属性和方法对所有提出服务请求的客户对象是公开的.
interface JobManager{
readonly attribute string FirstName;
attribute string status;
}
IDL接口继承:
单继承:
interface JobServer : JobManager{
......
}
多继承:
interface JobServer : JobServer, JobManager{
......
}
IDL异常处理:
exception DIVIDE_BY_ZERO{
string err;
}
IDL模块声明:
module 模块名{
//模块体
}
一个IDL文件示例:
module Compute // 对象实现模块
{
typedef double radius; // 圆的半径
typedef long times; // 算法迭代次数
interface PI // 对象实现模块接口
{
/* 计算圆周率 */
double getResult(in radius aRadius, in times time);
};
};
客户方码根: 客户方码根是服务端对象实现在客户端的虚实现的代码固化。它负责把客户端的请求进行编码发送到对象实现端,并对接收到的结果进行解码,把结果或异常信息返回给客户。是远程服务器对象的代理。
- 码根是自动生成的。
- 码根是静态的,一旦生成便不再改变。
- 码根于ORB的具体实现相关。
动态调用接口(DII): 当客户预先不知道服务对象的接口信息时,他首先通过查询或其他手段获得服务对象的接口描述信息,然后使用一个调用或一连串调用通过ORB所提供的方法来指定被调用的对象、所要执行的操作、以及这项操作的一组参数。此时客户必须提供关于所要执行的操作的信息以及要传送参数的类型。
//创建动态请求
void create_requests(...);
//返回请求执行的结果
void get_response() raises (WrongTransaction);
//判断是否有请求已经完成
boolean poll_next_response();
//返回完成的下一个请求
void get_next_response() raises (WrongTransaction);
ORB接口: ORB接口是ORB核心给出的界面. ORB接口同时为客户方和对象实现方所用, 提供了一些只能由ORB内核提供的服务ORB接口函数.
服务器静态IDL框架: 以代码固化的形式在服务器端负责与对象实现通信的接口。它负责对客户端发送过来的请求进行解码,定位所要求的对象的方法,执行(调用)该方法并把执行(调用)结果或异常信息编码后发送回客户端。
服务器动态IDL框架: 动态框架接口可以实现对象调用的动态处理,即在通过接口来达到对象实现时,这一接口不必通过专门用于某一操作的程序框架访问。
对象适配器: 由于对象特性的多样性使得ORB内核很难提供一个方便有效地用于所有对象的单一接口,并且为了避免对象实现与ORB内核之间的紧耦合,在ORB与对象实现之间引入对象适配器。从而使ORB可以通过对象适配器来对特定的对象实现提供服务。
2.3 ORB间互操作性
起初不同的厂商采用不同的通信格式导致无法相互通信. CORBA2.0规范增强了针对不同厂商的ORB系统之间的互操作的规范, 定义了通用ORB间通信协议(GIOP).
GIOP协议由三个元素组成: 公共数据表示(CDR), GIOP消息格式和GIOP传输规则.
CORBA规范中定义的另外一种ORB间的互操作协议是环境相关的ORB间互操作协议ESIOP.
桥接: 为了实现ORB间的通信, 通过在CORBA中引入嵌入桥接好请求级桥接, 使ORB在不需要了解对方ORB实现细节的情况下, 既可以实现ORB之间的操作.
2.4 CORBA编程
对象引用:
应用程序框架:
客户端:
服务器端:
CORBA运行流程:
使用Java IDL, 把经典的Hello World程序构建成支持应用程序客户机的CORBA分布式应用程序. 其中Hello World程序只做了一个操作, 即返回一个要打印的字符串.
这个Hello程序包括:
- 客户机调用HelloServer的sayHello()操作
- ORB把调用传给为IDL接口注册的提供服务的对象
- 提供服务的sayHello()方法运行并返回Java String
- ORB将该String传回客户机
- 客户机打印String的值
第一步: 编写IDL接口
Hello.idl
module HelloApp{
interface Hello{
string sayHello();
};
};
上述语句到Java语句的映射
IDL语句 | Java语句 |
---|---|
module HelloApp | package HelloApp; |
interface Hello | public interface Hello |
string sayHello(); | String sayHello(); |
第二步: 编写客户机应用程序
HelloClient.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class HelloClient{
public static void main(String args[]){
try{
ORB orb = ORB.init(args, null);
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("Hello", "");
NameComponent path[] = {nc};
Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));
String Hello = helloRef.sayHello();
System.out.println(Hello);
}catch(Exception e){
System.out.println("ERROR : " + e);
e.printStackTrace(System.out);
}
}
}
第三步: 编写Hello World服务器程序
HelloServer.java
import HelloApp.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
public class HelloServer{
public static void main(String args[]){
try{
ORB orb = ORB.init(args, null);
HelloServant helloRef = new HelloServant();
org.connect(helloRef);
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
NamingContext naRef = NamingContextHelper.narrow(objRef);
NameComponent nc = new NameComponent("Hello", "");
NameComponent path[] = {nc};
ncRef.rebind(path, helloRef);
java.lang.Object sync = new java.lang.Object();
synchronized(sync){
sync.wait();
}
}catch(Exception e){
System.err.println("ERROR: " + e);
e.printStackTrace(System.out);
}
}
}
class helloServant extends _HelloImplBase{
public String sayHello(){
return "\nHello world!!\n";
}
}
2.5 CORBA杂谈
CORBA未来趋势
- Agent技术与CORBA结合
- Java与CORBA结合
- 基于代理机制的CORBA
- C#与CORBA
总结
- CORBA是构造分布式Client/Server计算模型的一种方法,它通过使用ORB隔离对象的实现和使用来达到分隔系统的作用。
- CORBA是一个标准规范,而不是一种实现,它的实现依赖于CORBA到某个特定语言的映射及相关ORB产品的支持。
- CORBA使用OMG IDL语言描述客户机应用程序与服务器对象实现之间的接口关系。与CORBA相同,它也必须映射到某个具体的语言环境中才能被使用。
- CORBA的客户端和服务器端都有两种实现方式,组合起来CORBA系统中客户端应用程序与服务器端应用程序的交互方式有四种。
- 客户端使用服务器端对象实现的对象引用实现与服务器的交互,而不是直接访问服务器对象实现。
- 服务器与客户端的划分是就某个请求(对象实现)而言的,而不是指物理意义上的计算机。在某种情况下,一台计算机可能即是服务器又是客户端。
- CORBA程序设计的过程包括:定义对象接口(IDL文件);定制服务器端与ORB的交互方式;服务器端ORB及其接口初始化;对象实现编程;定制客户端与ORB的交互方式;客户端ORB及其接口初始化;客户端应用程序编程;客户端ORB接口编程。