38
山山山山山山山山山山山山山山山山山山山山山 第第第 第第 Corba 第第第第

第三章 简单 Corba 程序设计

Embed Size (px)

DESCRIPTION

第三章 简单 Corba 程序设计. 1 CORBA 应用开发过程. CORBA 规范并没有限制 ORB 的具体实现方法,所以不同厂商对 ORB 的具体实现方法可能差别很大,这就导致不同厂商提供的 ORB 上操作可能有很大的差异。但基本过程都是类似的。. 1.1 开发环境. Inprise VisiBroker 4.5 + JDK 1.3 + UltraEdit Inprise Visibroker 5 + JDK 1.4 ( + Jbuilder / SunOne Studio EE). 1.2 静态工作方式. 客户方. 对象实现方. IDL 构架(服务方代理). - PowerPoint PPT Presentation

Citation preview

Page 1: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院基础技术教学部

第三章简单 Corba程序设计

Page 2: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1 CORBA应用开发过程

CORBA规范并没有限制 ORB的具体实现方法,所以不同厂商对 ORB的具体实现方法可能差别很大,这就导致不同厂商提供的 ORB上操作可能有很大的差异。但基本过程都是类似的。

Page 3: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.1 开发环境

Inprise VisiBroker 4.5 + JDK 1.3 + UltraEdit

Inprise Visibroker 5 + JDK 1.4 ( + Jbuilder / SunOne

Studio EE)

Page 4: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.2 静态工作方式

客户方 对象实现方

IDL 桩(客户方代

理)

IDL 构架(服务方

代理)

ORB 内核

Page 5: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

设计一个静态方式的程序

IDL 文件对象实现

IDL 编译器JavaC++…

IDL 桩JavaC++…

IDL 构架JavaC++…

客户方调用

服务方主程序

Page 6: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.4典型的 CORBA应用实现过程

用 IDL编写对象规格说明

编译 IDL生成桩和框架

编写客户程序代码 编写对象实现和服务程序代码

编译客户程序 编译服务程序

运行客户程序 运行服务程序

启动对象请求代理( ORB)内核

一个典型 CORBA 应用的实现过程

Page 7: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

对象接口

对象接口实际上是分布式对象向外提供服务的规格说明

是客户程序与对象实现之间的一种合约,双方必须严格遵守对象接口定义中的约定,包括操作名字,参数表,返回表,异常表,上下文等

对象接口定义存放在一个或多个 IDL文本文件中,指明每一对象对外提供的服务,以及客户程序如何使用这些服务或处理服务的返回结果

Page 8: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.3 IDL语言

说明性语言,定义组件接口,不定义实现。 语法上可以看成 C++的一个子集,规定组件的属性、所继承的父类、产生的异常、事件和各类数据类型。

编译器作用:将 IDL映射到具体程序设计语言,产生桩代码和框架代码

调用请求经客户端桩传递给 ORB,然后转发到服务端框架,最后到达真正要执行请求的对象实现实例

Page 9: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

编写对象实现和服务程序

IDL文件只定义了对象的语法规格说明,必须编写这些对象的具体实现代码

对象实现可用各种语言实现,且与客户程序的语言无关 IDL到编程语言的映射规则

– 生成 IDL框架代码和各种辅助性的 java接口或类– 编写对象实现代码时必须继承或使用其中的某些接口或类

服务程序– 利用 POA激活伺服对象供客户对象使用– 通常是一个循环执行的进程,不断监听客户程序请求并为之服务

Page 10: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

编写客户程序

初始化 ORB

– 是应用程序进入 CORBA的起点– 作用

让 ORB 了解有新的成员加入获取 ORB 伪对象的引用,以备调用 ORB 内核提供的操作时使用

– 伪对象 (pseudo object):在 CORBA基础设施中的一个对象

获取分布式对象引用,利用其调用对象实现提供的服务

Page 11: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

创建并部署应用程序

客户端:客户程序代码与 IDL编译器自动生成的 ID

L桩代码一起编译 服务端:对象实现代码与服务程序代码与 IDL框架代码一起编译

Page 12: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5 例子背景

银行账户管理– 服务端管理大量银行顾客的账户,提供基本的开户、存款、取款、查询余额的功能。

Page 13: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.1 对象认定

一个银行帐户的实体模型。 balance :表示当前的余额。 deposit:存款 withdraw:取款 getBalance:查询余额

AccountManager

accountList : HashTable

open(name : String) : Account

manage 银行中的储蓄员的实体模型。 accountList :记录当前已开设的

所有帐户。 open :根据帐户标识查找某一帐

户,如果该标识的帐户不存在则创建一个新帐户。

Account

balance : float

deposit(amount : float) : voidwithdraw(amount : float) : booleangetBalance() : float

Page 14: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.2 定义对象接口

// 银行帐户管理系统的对象接口定义module Bank { // 帐户 interface Account { // 存款 void deposit(in float amount); // 取款 boolean withdraw(in float amount); // 查询余额 float getBalance(); };  // 帐户管理员 interface AccountManager { // 查询指定名字的帐户,查无则新开帐户 Account open(in string name); };};

Bank.idl

Page 15: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.3 生成 Stub与 Skeleton

IDL编译器作用是将 IDL映射到具体程序设计语言,产生桩代码和框架代码

Visibroker for java提供的编译器 idl2java将 IDL映射到 jav

a语言,生成 java语言的桩和框架语言 每个对象实例都有一个用于唯一标识自身的对象引用。客户程序利用对象引用指明调用的方向

表面上看,客户程序调用的是远程对象实现上的操作,实际被调用的代码是作为其代理的 IDL桩

Page 16: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成 Stub与 Skeleton

prompt> idl2java Bank.idl

idl2javaBank.idl

Stub

Skeleton输入

输出

其它辅助文件

Page 17: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4 生成 7个文件

VisiBroker for Java的 IDL编译器 idl2java为每个接口自动生成 7个文件:– AccountOperations.java– Account.java– _AccountStub.java– AccountPOA.java– AccountPOATie.java– AccountHelper.java– AccountHolder.java

Page 18: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4.1 生成的接口定义

Account.java和 AccountOperations.java定义了 IDL

接口 Account的完整基调。– AccountOperations.java(操作基调 )定义了 Account接口中定义的所有常量和方法。

package Bank; public interface AccountOperations//操作接口{ public void deposit(float amount); public boolean withdraw(float amount); public float getBalance();}

Page 19: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成的接口定义

– 客户程序代码中,程序员通常使用的是操作接口的派生接口 Ac

count( 位于 Account.java)

package Bank; public interface Account extends com.inprise.vbroker.CORBA.Object, Bank.AccountOperations, org.omg.CORBA.portable.IDLEntity{}

Page 20: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4.2 生成的 Stub

_AccountStub.java是 Account对象在客户端的桩代码,它实现了 Account接口。– 程序员编写的客户程序代码通常不直接调用这个类中的方法。– VisiBroker for Java生成了另外的辅助类 AccountHelper。

Page 21: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成的 Stub

package Bank; public class _AccountStub extends com.inprise.vbroker.CORBA.portable.ObjectImpl implements Account{ final public static java.lang.Class _opsClass =

Bank.AccountOperations.class; private static java.lang.String[] __ids =

{"IDL:Bank/Account:1.0"};  public java.lang.String[] _ids(){ return __ids; }  public void deposit(float amount){ //与 ORB交互,完成真正的 deposit方法调用 } public boolean withdraw(float amount){ //与 ORB交互,完成真正的 withdraw方法调用 } public float getBalance(){ //与 ORB交互,完成真正的 getBalance方法调用 }}

_AccountStub.java

Page 22: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4.3 生成的 Skeleton

AccountPOA.java是 Account对象的服务端框架代码,该类的功能:– 解包 in类型的参数并将参数传递给对象实现。– 打包返回值与所有 out类型的参数。

打包( marshal ):指将特定程序设计语言描述的数据类型转换为 CORBA 的 IIOP 流格式。

解包( unmarshal ):从 IIOP 流格式转换为依赖于具体程序设计语言的数据结构。

编写对象实现的最简单途径是继承这些 POA类,即把它们作为对象实现的基类。

Page 23: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成的 Skeleton

package Bank; public abstract class AccountPOA extends org.omg.PortableServer.Servant implements org.omg.CORBA.portable.InvokeHandler,

Bank.AccountOperations{ public static org.omg.CORBA.portable.OutputStream _invoke( ...) { org.omg.CORBA.portable.OutputStream _output = null; { switch (_method_id) { case 0: { float amount; amount = _input.read_float(); _self.deposit(amount); _output = _handler.createReply(); return _output; } case 1: {//...

} case 2: {//...

} }}}}

AccountPOA.java

Page 24: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4.4 生成的辅助工具类

IDL编译器为每一个用户自定义类型还生成一个辅助工具类。AccountHelper.java 声明了 AccountHelper类,该类为 Account接口定义了许多实用功能和支持功能的静态方法(又称类方法)。– 从 Any对象提取或向 Any对象插入对象( extract和 insert方法);– 从输入/输出流读写对象( read和 write方法);– 获取对象的库标识和类型码( id和 type方法);– 绑定对象与类型转换操作( bind 和 narrow 方法)等等。

编程时会用到该类中提供的方法。

Page 25: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成的辅助工具类

package Bank; public final class AccountHelper{ public static Bank.Account narrow

(final org.omg.CORBA.Object obj) { //... }  public static Bank.Account bind(org.omg.CORBA.ORB orb,

java.lang.String name) { //... } //...}

AccountHelper.java

Page 26: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.4.5 生成的对象传递支撑类

AccountHolder.java 声明的 AccountHolder类为传递对象提供支持。– IDL有三种参数传递方式: in、 out和 inout。– in类型的参数以及返回结果与 Java的参数传递方式与结果返回方式完全相同。

– out和 inout 两种类型的参数允许参数具有返回结果的能力,无法直接映射到 Java语言的参数传递机制,这时 AccountHolder

类为传递 out和 inout参数提供了一个托架( holder)。

Page 27: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

In表明实际参数从客户程序传向对象实现 Out表明数据从实现对象传递给客户程序,并且对象实现无需从客户程序获取参数的初始值

Inout表明数据从客户程序传给对象实现,然后经对象实现加工后再返回给客户程序

Page 28: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

生成的对象传递支撑类

package Bank; public final class AccountHolder implements org.omg.CORBA.portable.Streamable{ public Bank.Account value;  public AccountHolder() {}  public AccountHolder(final Bank.Account _vis_value){ this.value = _vis_value; }  public void _read(

final org.omg.CORBA.portable.InputStream input){ value = Bank.AccountHelper.read(input); }  public void _write(final

org.omg.CORBA.portable.OutputStream output){ Bank.AccountHelper.write(output, value); }  public org.omg.CORBA.TypeCode _type() { return Bank.AccountHelper.type(); }}

AccountHolder.java

Page 29: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.5 编写对象实现

对象实现代码所在的类名字可由程序员自由掌握,只要不与IDL编译器自动产生的 Java类产生名字冲突即可。客户程序也无须了解对象实现是由哪一个 Java类完成的。

CORBA应用程序的对象实现最常用、最简单的实现方式是使用继承,即直接继承由 IDL编译器生成的 xxxPOA类。– 当对象实现需要利用继承机制达到其他目的时,就必须改用 CORBA对象实现的另一种实现方式 ── 纽带机制( tie mechanism)。

我们的例子程序采用简单的继承方式编写对象实现。

Page 30: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

账户的对象实现

public class AccountImpl extends Bank.AccountPOA{ // 属性定义 protected float balance;  // 构造方法,按指定余额创建新的帐户 public AccountImpl(float bal){ balance = bal; }  // 往帐户中存款 public void deposit(float amount){ balance += amount; }  // 从帐户中取款,不足余额则返回 false public boolean withdraw(float amount){ if (balance < amount) return false;

else { balance -= amount; return true;}

}// 查询帐户余额public float getBalance(){

return balance}

}

AccountImpl.java

Page 31: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

账户管理员的对象实现

public class AccountManagerImpl extends Bank.AccountManagerPOA{ protected Hashtable accountList; // 该帐户管理员所负责的帐户清单 public AccountManagerImpl(){ accountList = new Hashtable(); } public synchronized Bank.Account open(String name){ Bank.Account account=(Bank.Account)accountList.get(name); if (account == null) { Random random = new Random(); float balance = Math.abs(random.nextInt())%100000/100f; AccountImpl accountServant = new AccountImpl(balance); try {

org.omg.CORBA.Object obj = _default_POA().servant_to_reference(accountServant);

account = Bank.AccountHelper.narrow(obj); } catch(Exception exc) { exc.printStackTrace(); } accountList.put(name, account); System.out.println("新开帐户: " + name); } return account; }}

AccountManagerImpl.java

Page 32: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.6 编写服务程序

通常程序员都会编写一个名为 Server.java的服务程序,服务程序创建伺服对象供客户端使用。

Page 33: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

编写服务程序

初始化 ORB

创建一个 POA

创建提供服务的伺服对象

激活伺服对象

激活 POA管理器

等待客户程序发来请求

服务程序的处理流程

Page 34: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

编写服务程序

public class Server{ public static void main(String[] args) { try { org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args, null); POA rootPOA = POAHelper.narrow( orb.resolve_initial_references("RootPOA")); org.omg.CORBA.Policy[] policies = { rootPOA.create_lifespan_policy(

LifespanPolicyValue.PERSISTENT) }; POA myPOA = rootPOA.create_POA("BankPOA", rootPOA.the_POAManager(), policies); AccountManagerImpl managerServant =

new AccountManagerImpl(); myPOA.activate_object_with_id( "BankManager".getBytes(), managerServant); rootPOA.the_POAManager().activate(); System.out.println("帐户管理员 BankManager已就绪 ...\n"); orb.run(); } catch(Exception exc) { exc.printStackTrace(); } }}

服务程序 Server.java

初始化 ORB

创建一个 POA

创建提供服务的伺服对象

激活伺服对象

激活 POA管理器

等待客户程序发来请求

Page 35: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.7 编写客户程序

初始化 ORB

绑定到服务对象

调用服务对象提供的服务

客户程序操作流程

Page 36: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

编写客户程序

public class Client{ public static void main(String[] args) { org.omg.CORBA.ORB orb=org.omg.CORBA.ORB.init(args, null); // 利用 POA全称与对象标识 "BankManager"查找帐户管理员 Bank.AccountManager manager =

Bank.AccountManagerHelper.bind( orb, "/BankPOA", "BankManager".getBytes()); String name = args.length > 0 ? args[0] : "David Zeng"; // 请求帐户管理员找出一个指定名字的帐户,无此帐户则新开一个 Bank.Account account = manager.open(name); System.out.println(name + “的帐户余额为” +

account.getBalance() + "元 "); account.deposit(200); System.out.println(“存款 200元后,余额为” +

account.getBalance() + “元” ); if (account.withdraw(600)) { System.out.println(“取款 600元后,余额为” +

account.getBalance() + "元 "); } else { System.out.println("余额不足 600元,取款失败,余额保持不变 "); } }}

客户程序 Client.java

初始化 ORB

绑定到服务对象

调用服务对象提供的服务

Page 37: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.8 编译应用程序

利用 VisiBroker for Java提供的编译器 vbjc 完成这一工作:– prompt> vbjc Server.java

– prompt> vbjc Client.java

vbjc实际上封装了 JDK提供的 Java编译器。 Holder类和 POATie类需要指定额外的参数才会生成。

Page 38: 第三章 简单 Corba 程序设计

山东大学计算机科学与技术学院

1.5.9 运行应用程序

按一定的顺序启动应用程序– 1. 启动智能代理

运行 CORBA 应用程序之前,网络中必须至少有一台主机上启动了智能代理 osagent 。这是 VisiBroker 特有的分布式位置服务( location service )守护进程,网络中多个智能代理可协作以查找合适的对象实现。

prompt> osagent

– 2.启动服务程序 prompt> start vbj Server

– 3.启动客户程序 prompt> vbj Client