9.6 一个 rmi 的分布式应用的实例
DESCRIPTION
9.6 一个 RMI 的分布式应用的实例. 用 RMI 编写一个分布式应用 , 核心有以下三方面: 定位远程对象 1. 一个应用可以利用 RMI 的名字服务功能注册器远程对象。 2. 可以象操作普通对象一样传送并返回一个远程对象的引用 ( 指针 ) 。 与远程对象通信: 底层的通信由 RMI 实现,对于系统开发人员来说,远程调用和标准的 Java 方法调用没有什么区别。 为需要传递的对象装载类的字节码 RMI 允许调用者向远程对象传递一个对象,因此 RMI 提供这种装载对象的机制。. 9.6 一个 RMI 的分布式应用的实例. Web Server. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/1.jpg)
北京大
学
计算机
系
代亚
非
1
9.6 一个 RMI 的分布式应用的实例• 用 RMI 编写一个分布式应用 , 核心有以下三方面:• 定位远程对象
– 1. 一个应用可以利用 RMI 的名字服务功能注册器远程对象。
– 2. 可以象操作普通对象一样传送并返回一个远程对象的引用 ( 指针 ) 。
• 与远程对象通信:– 底层的通信由 RMI 实现,对于系统开发人员来说,远
程调用和标准的 Java 方法调用没有什么区别。• 为需要传递的对象装载类的字节码
– RMI 允许调用者向远程对象传递一个对象,因此 RMI 提供这种装载对象的机制。
![Page 2: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/2.jpg)
北京大
学
计算机
系
代亚
非
2
9.6 一个 RMI 的分布式应用的实例
Web Server Client
Server
Web Server registryURL protocol
RMI
RMI
URL protocol
URL protocol
RMI
![Page 3: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/3.jpg)
北京大
学
计算机
系
代亚
非
3
9.6 一个 RMI 的分布式应用的实例
Compute engin
Server
Remote object
Client
task
Client
task
Client
task
一、问题的提出
![Page 4: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/4.jpg)
北京大
学
计算机
系
代亚
非
4
9.6 一个 RMI 的分布式应用的实例
• 分布特点 :– engin 开发 , 先运行 ,task 后定义 . 写 engin 时不对执行
什么任务作任何规定 . 任务可以是任意定制的 .
• 前提条件 :– 定义任务的类 , 要规定任务的实现步骤 , 使得这个任务
能够提交给 engin 去执行 . 使用 server 上的 CPU 资源 .
• 技术支持 :– RMI 的动态装载功能 .
![Page 5: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/5.jpg)
北京大
学
计算机
系
代亚
非
5
9.6 一个 RMI 的分布式应用的实例
远程对象
client server
A
m1
远程方法
A.m1()
远程对象必须继承远程接口确定那些方法是远程方法 , 为此定义远程接口远程接口只负责提供方法名 , 不一共实现细节 , 因此必须由一个对象来实现接口
executeTask
computeengine
Compute
execute
Task
![Page 6: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/6.jpg)
北京大
学
计算机
系
代亚
非
6
9.6 一个 RMI 的分布式应用的实例• 二、设计一个服务器• 核心协议 : 提交任务 , 执行任务 , 返回结果
clientclient
• 在 java 中远程调用是通过定义远程接口来实现的 , 一个接口只能有一个方法
• 不同类型的任务 , 只要他们实现了 Task 类型 , 就可以在 engin 上运行 .
• 实现这个接口的类 , 可以包含任何任务计算需要的数据以及和任何任务计算需要的方法 .
![Page 7: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/7.jpg)
北京大
学
计算机
系
代亚
非
7
9.6 一个 RMI 的分布式应用的实例( 1 )定义远程接口• 第一个接口 :compute
package compute;import java.rmi.Remote;import java.rmi.RemoteException;public interface Compute extends Remote { Object executeTask(Task t) throws RemoteException;}
package compute;import java.io.Serializable;public interface Task extends Serializable{ Object execute(); }
第二个接口 : 定义一个 task 类型 ,作为参数传给 executeTask 方法 ,
规定了 engin 与它的任务之间的接口 , 以及如何启动它的任务 .它 不是一个远程接口
executeTask
computeengine
Compute
execute
Task
![Page 8: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/8.jpg)
北京大
学
计算机
系
代亚
非
8
9.6 一个 RMI 的分布式应用的实例• Compute engin 的设计要考虑以下问题 :• 1. compute engine 是一个类 ComputeEngine , 它实
现了 Compute 接口 , 只要调用该类的方法 executeTask, 任务就能提交上来 .
• 2. 提交任务的 Client 端程序并不知道任务是被下载到 engin 上执行的 . 因此 client 在定义任务时并不需要包含如何安装的 server 端的代码 .
• 3. 返回类型是对象 , 如果结果是基本类型 , 需要转化成相应的对等类 .
• 4. 用规定任务如何执行的代码填写 execute 方法 .
![Page 9: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/9.jpg)
北京大
学
计算机
系
代亚
非
9
9.6 一个 RMI 的分布式应用的实例
( 2 )实现远程接口• 一般说来 , 实现一个远程接口的类至少有以下步骤 :• 1. 声明远程接口• 2. 为远程对象定义构造函数• 3. 实现远程方法engin 中创建对象的工作可以在实现远程接口类的 m
ain 函数中实现 :• 1. 创建并安装安全管理器• 2. 创建一个或更多的远程对象的实例• 3. 至少注册一个远程对象
![Page 10: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/10.jpg)
北京大
学
计算机
系
代亚
非
10
9.6 一个 RMI 的分布式应用的实例package engine;import java.rmi.*; import java.rmi.server.*; import compute.*;
public class ComputeEngine extends UnicastRemoteObject implements Compute{ public ComputeEngine() throws RemoteException { super(); }
public Object executeTask(Task t)
{ return t.execute(); }
public static void main(String[] args)
{ if (System.getSecurityManager() == null)
{ System.setSecurityManager(new RMISecurityManager()); }
String name = "//host/Compute";
try { Compute engine = new ComputeEngine();
Naming.rebind(name, engine);
System.out.println("ComputeEngine bound");
} catch (Exception e) { System.err.println("ComputeEngine exception: " + e.getMessage()); e.printStackTrace(); }}
![Page 11: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/11.jpg)
北京大
学
计算机
系
代亚
非
11
9.6 一个 RMI 的分布式应用的实例
• 在构造函数中 , 通过 super(), a UnicastRemoteObject 被启动 , 即它可以侦听客户端来的请求输入
• 只有一个远程方法 , 参数是客户端远程调用这个方法时传来的任务 . 这个任务被下载到 engin, 远程方法的内容就是调用客户端任务的方法 , 并把结果回送给调用者 . 实际上这个结果是在客户的任务的方法中体现的 .
executeTask
computeengine
Compute
execute
TaskcallexecuteTask(task)
![Page 12: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/12.jpg)
北京大
学
计算机
系
代亚
非
12
9.6 一个 RMI 的分布式应用的实例• 参数传递规则 :• 1. 远程对象通常通过引用传递 . 一个远程对象的
引用是一个 stub, 它是客户端的代理 . 它实现远程对象中的远程接口的内容
• 2. 本地对象通过串行化拷贝到目的 . 如果不作制定 , 对象的所有成员都将被拷贝 .
![Page 13: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/13.jpg)
北京大
学
计算机
系
代亚
非
13
9.6 一个 RMI 的分布式应用的实例
• 通过引用传递一个对象,意味着任何由于远程调用引起的变化都能反映在原始的对象中。
• 当传递一个远程对象时,只有远程接口是可用的, 而在实现类中定义的方法或者是非远程接口中的方法,对接收者来说是不可用的
• 在远程方法调用中,参数,返回值,异常等非对象是值传送 . 这意味着对象的拷贝被传送到接受方。任何在对象上发生的变化不影响原始的对象
• 一旦服务器用 rmi 注册了, main 方法就存在了,不需要一个守护线程工作维护服务器的工作状态,只要有一个 computer engin 的引用在另一个虚拟机,computer engin 就不会关闭
![Page 14: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/14.jpg)
北京大
学
计算机
系
代亚
非
14
9.6 一个 RMI 的分布式应用的实例
三、实现一个客户程序• 目标:创建一个任务,并规定如何执行这个任务。
client
Pi computePi
package compute;public interface Task extends java.io.Serializable { Object execute();}
• task 不是远程接口,但是需要传递到服务器,因此用串行化
ExecuteTask()execute()
![Page 15: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/15.jpg)
北京大
学
计算机
系
代亚
非
15
9.6 一个 RMI 的分布式应用的实例• computePi 的作用
装载安全管理器
生成一个远程对象 comp
生成任务对象
Look up(ComputeEngin),获得了 stubs
Pi task=new Pi()
调用 ComputeEngin 的远程方法获得计算结果
Comp.executeTask(task)
![Page 16: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/16.jpg)
北京大
学
计算机
系
代亚
非
16
9.6 一个 RMI 的分布式应用的实例package client;
import java.rmi.*; import java.math.*; import compute.*;
public class ComputePi {
public static void main(String args[]) {
if (System.getSecurityManager() == null)
{ System.setSecurityManager(new RMISecurityManager()); }
try { String name = "//" + args[0] + "/Compute";
Compute comp = (Compute) Naming.lookup(name);
Pi task = new Pi(Integer.parseInt(args[1]));
BigDecimal pi = (BigDecimal) (comp.executeTask(task));
System.out.println(pi);
} catch (Exception e) {
System.err.println("ComputePi exception: " + e.getMessage());
e.printStackTrace(); } }}
![Page 17: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/17.jpg)
北京大
学
计算机
系
代亚
非
17
9.6 一个 RMI 的分布式应用的实例
• Pi 的作用
computepi
rmiregistry
Compute
engin
实现 Task 接口
实现 execute 算法
![Page 18: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/18.jpg)
北京大
学
计算机
系
代亚
非
18
9.6 一个 RMI 的分布式应用的实例package client;
import compute.*; import java.math.*;
public class Pi implements Task {
private static final BigDecimal ZERO =
BigDecimal.valueOf(0);
private static final BigDecimal ONE =
BigDecimal.valueOf(1);
private static final BigDecimal FOUR =
BigDecimal.valueOf(4);
private static final int roundingMode =
BigDecimal.ROUND_HALF_EVEN;
public Pi(int digits)
{ this.digits = digits; }
![Page 19: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/19.jpg)
北京大
学
计算机
系
代亚
非
19
9.6 一个 RMI 的分布式应用的实例public Object execute()
{ return computePi(digits); }
***************************************************
* pi/4 = 4*arctan(1/5) - arctan(1/239)
****************************************************
public static BigDecimal computePi(int digits) {
int scale = digits + 5;
BigDecimal arctan1_5 = arctan(5, scale);
BigDecimal arctan1_239 = arctan(239, scale);
BigDecimal pi
arctan1_5.multiply(FOUR).subtract(arctan1_239).multiply(FOUR);
return pi.setScale(digits, BigDecimal.ROUND_HALF_UP);
}
![Page 20: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/20.jpg)
北京大
学
计算机
系
代亚
非
20
9.6 一个 RMI 的分布式应用的实例 /**
* Compute the value, in radians, of the arctangent of
* the inverse of the supplied integer to the speficied
* number of digits after the decimal point. The value
* is computed using the power series expansion for the
* arctangent:
* arctan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 +
* (x^9)/9 ...
*/
![Page 21: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/21.jpg)
北京大
学
计算机
系
代亚
非
21
9.6 一个 RMI 的分布式应用的实例public static BigDecimal arctan(int inverseX, int scale) { BigDecimal result, numer, term; BigDecimal invX = BigDecimal.valueOf(inverseX); BigDecimal invX2 = BigDecimal.valueOf(inverseX * inverseX); numer = ONE.divide(invX, scale, roundingMode); result = numer; int i = 1; do { numer =numer.divide(invX2, scale, roundingMode); int denom = 2 * i + 1; term = numer.divide(BigDecimal.valueOf(denom), scale, roundingMode); if ((i % 2) != 0) { result = result.subtract(term); } else { result = result.add(term); } i++; } while (term.compareTo(ZERO) != 0); return result; }}
![Page 22: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/22.jpg)
北京大
学
计算机
系
代亚
非
22
9.6 一个 RMI 的分布式应用的实例
• 由于 Rmi 的存在,系统可以做到:• 1 、可以直接通过名字定位远程方法的位置• 2 、以参数的形式将一个对象传递给一个远程方
法• 3 、可以使一个对象到另外一个虚拟机上运行• 4 、计算结果可以返回
![Page 23: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/23.jpg)
北京大
学
计算机
系
代亚
非
23
9.6 一个 RMI 的分布式应用的实例
• 将接口,远程对象,客户代码分成三个程序包:• 1. compute ( Compute and Task interfaces) • 2. engine ( ComputeEngine implementation class
and its stub) • 3. client ( ComputePi client code and Pi task imple
mentation)
![Page 24: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/24.jpg)
北京大
学
计算机
系
代亚
非
24
9.6 一个 RMI 的分布式应用的实例
• 接口 compute 对于编程双方都是需要的 , 通常将接口文件打成包 , 分发给 server 和 client 的开发者 :
• 假设接口的开发者将写好的接口程序放在c:\home\waldo\src\compute 目录下
• cd c:\home\waldo\src• javac compute\Compute.java• javac compute\Task.java• jar cvf compute.jar compute\*.class
![Page 25: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/25.jpg)
北京大
学
计算机
系
代亚
非
25
9.6 一个 RMI 的分布式应用的实例• 类文件必须是网络可访问的 ,rmi 利用 URL 定位
类文件• 假设 ComputeEngine.java 存放在 c:\home\ann\src\engine • 假设 compute.jar存放在 c:\home\ann\public_html\classes. • 设置环境变量• CLASSPATH=c:\home\ann\src;c:\home\ann\publ
ic_html\classes\compute.jar
![Page 26: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/26.jpg)
北京大
学
计算机
系
代亚
非
26
9.6 一个 RMI 的分布式应用的实例• 编译 ComputeEngine.java,产生一个 stub, 并使 st
ub 是网络可访问的 . • 产生 stub 的命令是 rmic,生成的文件形式为 :
className_Stubs.class 和 className_skeleton.class• 命令如下 :• cd c:\home\ann\src• javac engine\ComputeEngine.java• rmic -d . engine.ComputeEngine• md c:\home\ann\public_html\classes\engine• copy engine\ComputeEngine_*.class
c:\home\ann\public_html\classes\engine
![Page 27: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/27.jpg)
北京大
学
计算机
系
代亚
非
27
9.6 一个 RMI 的分布式应用的实例
• 展开接口文件• cd c:\home\ann\public_html\classes• jar xvf compute.jar
![Page 28: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/28.jpg)
北京大
学
计算机
系
代亚
非
28
9.6 一个 RMI 的分布式应用的实例• 执行程序• 1. 在启动‘ compute engine’ 之前 , 首先要启动 RMI
的 registry 。– unset CLASSPATH
– start rmiregistry
• 2. 启动 Server.• 确认 compute.jar文件和实现远程对象的类在指定的
class路径下– set CLASSPATH=
c:\home\ann\src;c:\home\ann\public_html\classes\compute.jar
![Page 29: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/29.jpg)
北京大
学
计算机
系
代亚
非
29
9.6 一个 RMI 的分布式应用的实例
• 启动 compute engine 时 , 要规定服务器端的类在什么情况下是可用的。启动’ Compute engine’– java -Djava.rmi.server.codebase=
file:/c:\home\ann\public_html\classes/
-Djava.rmi.server.hostname=
zaphod.east.sun.com
-Djava.security.policy=java.policy
engine.ComputeEngine
•
![Page 30: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/30.jpg)
北京大
学
计算机
系
代亚
非
30
9.6 一个 RMI 的分布式应用的实例3. 启动 Client
指定类 (pi) 的位置 –set CLASSPATH=
c:\home\jones\src;
c:\home\jones\public_html\classes\compute.jar
-java -Djava.rmi.server.codebase=
file:/c:\home\jones\public_html\classes/
-Djava.security.policy=java.policy
–client.ComputePi localhost 20
•输入完上述命令后,得到结果• 3.14159265358979323846
![Page 31: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/31.jpg)
北京大
学
计算机
系
代亚
非
31
9.6 一个 RMI 的分布式应用的实例
![Page 32: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/32.jpg)
北京大
学
计算机
系
代亚
非
32
9.7 基于 CORBA 的分布式应用系统的实例
windowsNT
( C++ )
Sun
( Java )
Netscape
( COBOL )
client
![Page 33: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/33.jpg)
北京大
学
计算机
系
代亚
非
33
9.7 基于 CORBA 的分布式应用系统的实例• CORBA 技术和 Java 技术的结合 --Java IDL• 什么是 IDL?• IDL 是 CORBA 规范中的接口定义语言 , 不依赖于
任何具体的编程语言 .• CORBA 提供了到各种不同语言的 IDL 映射 .• Java IDL 是 CORBA 到 Java 的映射 , 使 Java也
支持 CORBA 规范• Java IDL 和 Java RMI 非常相似 ,RMI 只支持 Jav
a语言写的分布对象 ,Java IDL 可以和 CORBA 支持的任何一种语言编写的 ORB 对象进行交互
• Java RMI 和 Java IDL 目前使用的通信协议不同 ,分别是 JRMP 和 IIOP.
![Page 34: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/34.jpg)
北京大
学
计算机
系
代亚
非
34
9.7 基于 CORBA 的分布式应用系统的实例
• 在 Java IDL 中 , 客户端通过引用与远程的对象进行交互 , 即客户机使用 stubs 对远程服务器上的对象进行操作 ,但并不拷贝服务器上的对象 .
• Java RMI 即可以通过引用 ,也可以将对象下载到本地机上运行 ( 因为有串行化功能 ).
• Java 实现简单 ,但语言不兼容• Java IDL 则可以充分发挥语言无关的优势
![Page 35: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/35.jpg)
北京大
学
计算机
系
代亚
非
35
9.7 基于 CORBA 的分布式应用系统的实例• IDL Java 的技术组成 :
– IDL 至 Java 的编译器 :idltojava
– 生成客户端的 stubs 和服务器端的 skeleton
– CORBA API 和 ORB
– 一个简单的名字服务
![Page 36: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/36.jpg)
北京大
学
计算机
系
代亚
非
36
9.7 基于 CORBA 的分布式应用系统的实例
IDL 接口IDL 编译器
( C++, Java )
服务程序
IDL Stub
客户应用
对象实现
Skeleton
C++, Java 编译器
C++, Java 编译器
客户程序
应用开发者
![Page 37: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/37.jpg)
北京大
学
计算机
系
代亚
非
37
9.7 基于 CORBA 的分布式应用系统的实例
ORB 内核BOA
IDL SkeletonIDL 文件 IDL 编译器
对象实现应用开发者
事件感知部分
事件适配部分
事件处理分发部分
事件处理部分
从反应式 Agent 的角度看
![Page 38: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/38.jpg)
北京大
学
计算机
系
代亚
非
38
9.7 基于 CORBA 的分布式应用系统的实例• CORBA 编程实例• 运行在浏览器中的客户对象与远程的服务对象交互 , 客户端的表现是在浏览器中点击一个 button ,就会在一个文本域中返回服务端的时间,同时也在服务端的标准输出上打印该时间。
button
The data in server side is
2000.6.112 : 56 : 00 server
时间是一个对象
![Page 39: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/39.jpg)
北京大
学
计算机
系
代亚
非
39
9.7 基于 CORBA 的分布式应用系统的实例
ORB
CLIENT
STUBS SKELETONS
SERVER
ORBIIOP
METHOD REQUEST
OBJECT REFERENCE SERVANT
![Page 40: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/40.jpg)
北京大
学
计算机
系
代亚
非
40
9.7 基于 CORBA 的分布式应用系统的实例1. 首先是定义交互接口,在文件 dateit.idl 中。
– module TheDate (相当于包)– { interface DateIt
– { string dateit(); };
– };
2. 用 IDL 接口到 Java语言的映射– jidl dateit.idl 该命令会生成几个相关的 java文件:– DateIt.java
– DateItHelper.java
– DateItHolder.java
– _DateItImplBase.java
– StubForDateIt.java
![Page 41: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/41.jpg)
北京大
学
计算机
系
代亚
非
41
9.7 基于 CORBA 的分布式应用系统的实例3. 编写服务对象的程序,在文件 DateIt_impl.java 中
package TheDate; // jidl 产生的 Java文件放在 TheDate 包中import org.omg.CORBA.*; import java.io.*;
import java.awt.*;import java.util.Date;
import java.lang.System;
public class DateIt_impl extends _DateItImplBase
//扩展了 jidl 生成的抽象类 _DateItImplBase
{ String date_time;
public String dateit()
{ date_time=(new Date()).toString(); //获取时间 System.out.println(date_time);
return date_time;// 向客户端返回时间串 }}
![Page 42: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/42.jpg)
北京大
学
计算机
系
代亚
非
42
9.7 基于 CORBA 的分布式应用系统的实例4. 编写服务方的程序,在文件 Server.java 中。
package TheDate;
import org.omg.CORBA.*;import java.io.*;
public class Server
{ public static void main(String args[])
{try {
// 创建 ORB 和 BOA 对象实例 ORB orb = ORB.init(args, new java.util.Properties());
// 生成服务对象实例 BOA boa = orb.BOA_init(args);
DateIt_impl p = new DateIt_impl(); // 创建服务对象实例
![Page 43: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/43.jpg)
北京大
学
计算机
系
代亚
非
43
9.7 基于 CORBA 的分布式应用系统的实例// 保存引用try { String ref = orb.object_to_string(p);
// 将对象编码成字符串 String refFile = "date.ref";
FileOutputStream file = new FileOutputStream(refFile);
PrintStream out = new PrintStream(file);
out.println(ref); //存入文件 date.ref 中 out.flush(); file.close();
}catch(IOException ex)
{ System.err.println("Can't write to" +ex.getMessage());
System.exit(1);
}
![Page 44: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/44.jpg)
北京大
学
计算机
系
代亚
非
44
9.7 基于 CORBA 的分布式应用系统的实例
// 将引用存入 html文件中,参见后面列出的 date.html 文try { String ref = orb.object_to_string(p);
String refFile = "c:\\Inetpub\\wwwroot\\Docs\\date.html";
FileOutputStream file = new FileOutputStream(refFile);
PrintStream out = new PrintStream(file);
out.println("<applet codebase=
\"http://202.118.243.55/docs\" ”+ "code=
\"TheDate/Client.class\" " +”
width=500 height=300>");
![Page 45: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/45.jpg)
北京大
学
计算机
系
代亚
非
45
9.7 基于 CORBA 的分布式应用系统的实例// 指由 Client.java 编译成的 class文件out.println("<param name=ior value=\"" + ref + "\">");
// 将由服务对象转化成的字符串存入超文本文件中out.println("<param name=org.omg.CORBA.ORBClass " + "value=com.aic.CORBA.IIOPORB>");
out.println("<param =com.aic.CORBA.ORBSingleton>");
name=org.omg.CORBA.ORBSingletonClass " + "value out.println("</applet>");
out.flush(); file.close();
// 这样浏览器调入该超文本页面时,会运行 Client.class 的 applet ,并将包含标识服务对象的字符串由参数 ior 传递给 applet 。} catch(IOException ex) {
System.err.println(“Can't write to ”+ex.getMessage()+“”);
System.exit(1); }
![Page 46: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/46.jpg)
北京大
学
计算机
系
代亚
非
46
9.7 基于 CORBA 的分布式应用系统的实例
// 服务对象就绪,准备接受请boa.impl_is_ready(null);
System.exit(0);
} catch(SystemException ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
System.exit(1);
}
}
}
![Page 47: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/47.jpg)
北京大
学
计算机
系
代亚
非
47
9.7 基于 CORBA 的分布式应用系统的实例
• 5. 编写客户方的程序,在文件 Client.java 中。package TheDate;// 由于 jidl产生的 JAVA文件放在 packag
e TheDate 中,因此该语句是必须的import org.omg.CORBA.*;
import java.io.*;
import java.awt.*;
import java.util.Date;
import java.lang.System;
![Page 48: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/48.jpg)
北京大
学
计算机
系
代亚
非
48
9.6 各种主流技术的主要开发过程 --CORBA
public class Client extends java.applet.Applet
{ private DateIt serverdate;
private Button button;
private TextField outdate;
public void init()
{ String ior = getParameter("ior");
//Applet 只能从包含它的 HTML文件获取 IOR 串 见 Server.java.
// 产生 ORB 实例 ORB orb = ORB.init(this, null);
// Create client object
org.omg.CORBA.Object obj = orb.string_to_object(ior);
![Page 49: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/49.jpg)
北京大
学
计算机
系
代亚
非
49
9.6 各种主流技术的主要开发过程 --CORBA
// 串到对象的转化 if(obj == null) throw new RuntimeException();
serverdate = DateItHelper.narrow(obj);
//产生对象实例,其实是服务对象的映射// 添加 serverdate按钮和文字域 button = new Button("Dateis");
outdate = new TextField("",30);
this.add(button);
this.add(outdate);
}
![Page 50: 9.6 一个 RMI 的分布式应用的实例](https://reader031.vdocuments.net/reader031/viewer/2022020918/56814523550346895db1e759/html5/thumbnails/50.jpg)
北京大
学
计算机
系
代亚
非
50
9.6 各种主流技术的主要开发过程 --CORBA
// 事件处理 // public boolean action(Event event, java.lang.Object arg)
{ if(event.target == button)
{ outdate.setText("please wait...");
outdate.setText(serverdate.dateit());
// 调用服务对象的函数,返回服务端的时间 return true;
}
else
return super.action(event, arg);
}
}