友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
一世书城 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第214章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




系列服务,它们可通过标准接口访问。  

  

1。 CORBA 接口定义语言(IDL)  

CORBA 是面向语言的透明而设计的:一个客户对象可调用属于不同类的服务器对象方法,无论对方是用何种 

语言实现的。当然,客户对象事先必须知道由服务器对象揭示的方法名称及签名。这时便要用到 IDL。CORBA  

IDL是一种与语言无关的设计方法,可用它指定数据类型、属性、操作、接口以及更多的东西。IDL 的语法类 

似于C++或 Java 语法。下面这张表格为大家总结了三种语言一些通用概念,并展示了它们的对应关系。  

  

CORBA IDL Java C++  

  

模块(Module) 包(Package) 命名空间(Namespace)  

接口(Interface) 接口(Interface) 纯抽象类(Pure abstract class)  

方法(Method) 方法(Method) 成员函数(Member function)  

  

继承概念也获得了支持——就象C++那样,同样使用冒号运算符。针对需要由服务器和客户实现和使用的属 

性、方法以及接口,程序员要写出一个 IDL描述。随后,IDL会由一个由厂商提供的 IDL/Java 编译器进行编 

译,后者会读取 IDL源码,并生成相应的Java 代码。  

IDL编译器是一个相当有用的工具:它不仅生成与 IDL等价的 Java 源码,也会生成用于汇集方法自变量的代 

码,并可发出远程调用。我们将这种代码称为“根干”(Stub and Skeleton)代码,它组织成多个Java 源 

文件,而且通常属于同一个Java 包的一部分。  

  

2。 命名服务  

命名服务属于CORBA 基本服务之一。CORBA 对象是通过一个引用访问的。尽管引用信息用我们的眼睛来看没 

什么意义,但可为引用分配由程序员定义的字串名。这一操作叫作“引用的字串化”。一个叫作“命名服 

务”(Naming Service)的OMA 组件专门用于执行“字串到对象”以及“对象到字串”转换及映射。由于命 

名服务扮演了服务器和客户都能查询和操作的一个电话本的角色,所以它作为一个独立的进程运行。创建 

 “对象到字串”映射的过程叫作“绑定一个对象”;删除映射关系的过程叫作“取消绑定”;而让对象引用 

传递一个字串的过程叫作“解析名称”。  

比如在启动的时候,服务器应用可创建一个服务器对象,将对象同命名服务绑定起来,然后等候客户发出请 

求。客户首先获得一个服务器引用,解析出字串名,然后通过引用发出对服务器的调用。  

同样地,“命名服务”规范也属于CORBA 的一部分,但实现它的应用程序是由ORB 厂商(开发商)提供的。 

由于厂商不同,我们访问命名服务的方式也可能有所区别。  



A。6。2  一个例子  



这儿显示的代码可能并不详尽,因为不同的ORB 有不同的方法来访问CORBA 服务,所以无论什么例子都要取 

决于具体的厂商(下例使用了JavaIDL,这是 Sun 公司的一个免费产品。它配套提供了一个简化版本的ORB、 

一个命名服务以及一个“IDL→Java ”编译器)。除此之外,由于 Java 仍处在发展初期,所以在不同的 

Java/CORBA 产品里并不是包含了所有 CORBA 特性。  

我们希望实现一个服务器,令其在一些机器上运行,其他机器能向它查询正确的时间。我们也希望实现一个 

客户,令其请求正确的时间。在这种情况下,我们让两个程序都用Java 实现。但在实际应用中,往往分别采 

用不同的语言。  

  

1。 编写 IDL源码  



                                                                       667 


…………………………………………………………Page 669……………………………………………………………

第一步是为提供的服务编写一个 IDL描述。这通常是由服务器程序员完成的。随后,程序员就可用任何语言 

实现服务器,只需那种语言里存在着一个CORBA IDL 编译器。  

IDL文件已分发给客户端的程序员,并成为两种语言间的桥梁。  

下面这个例子展示了时间服务器的 IDL描述情况:  

  

module RemoteTime {  

   interface ExactTime {  

      string getTime();  

   };  

};  

  

这是对 RemoteTime 命名空间内的 ExactTime 接口的一个声明。该接口由单独一个方法构成,它以字串格式返 

回当前时间。  

  

2。 创建根干  

第二步是编译 IDL,创建Java 根干代码。我们将利用这些代码实现客户和服务器。与JavaIDL 产品配套提供 

的工具是idltojava:  

idltojava …fserver …fclient RemoteTime。idl  

其中两个标记告诉 idltojava 同时为根和干生成代码。idltojava 会生成一个 Java 包,它在 IDL模块、 

RemoteTime 以及生成的Java 文件置入 RemoteTime 子目录后命名。_ExactTimeImplBase。java 代表我们用于 

实现服务器对象的“干”;而_ExactTimeStub。java 将用于客户。在ExactTime。java 中,用Java 方式表示 

了IDL 接口。此外还包含了用到的其他支持文件,例如用于简化访问命名服务的文件。  

  

3。 实现服务器和客户  

大家在下面看到的是服务器端使用的代码。服务器对象是在ExactTimeServer 类里实现的。 

RemoteTimeServer 这个应用的作用是:创建一个服务器对象,通过 ORB 为其注册,指定对象引用时采用的名 

称,然后“安静”地等候客户发出请求。  

  

import RemoteTime。*;  

  

import org。omg。CosNaming。*;  

import org。omg。CosNaming。NamingContextPackage。*;  

import org。omg。CORBA。*;  

  

import java。util。*;  

import java。text。*;  

  

// Server object implementation  

class ExactTimeServer extends _ExactTimeImplBase{  

  public String getTime(){  

    return DateFormat。  

        getTimeInstance(DateFormat。FULL)。  

          format(new Date(  

              System。currentTimeMillis()));  

  }  

}  

  

// Remote application implementation  

public class RemoteTimeServer {  

  public static void main(String args'')  {  

    try {  

      // ORB creation and initialization:  



                                                                                             668 


…………………………………………………………Page 670……………………………………………………………

      ORB orb = ORB。init(args; null);  

      // Create the server object and register it:  

      ExactTimeServer timeServerObjRef =   

        new ExactTimeServer();  

      orb。connect(timeServerObjRef);  

      // Get the root naming context:  

      org。omg。CORBA。Object objRef =   

        orb。resolve_initial_references(  

          〃NameService〃);  

      NamingContext ncRef =   

        NamingContextHelper。narrow(objRef);  

      // Assign a string name to the   

      // object reference (binding):  

      Nameponent nc =   

        new Nameponent(〃ExactTime〃; 〃〃);  

      Nameponent path'' = {nc};  

      ncRef。rebind(path; timeServerObjRef);  

      // Wait for client requests:  

      java。lang。Object sync =  

        new java。lang。Object();  

      synchronized(sync){  

        sync。wait();  

      }  

    }  

    catch (Exception e)  {  

      System。out。println(  

         〃Remote Time server error: 〃 + e);  

      e。printStackTrace(System。out);  

    }  

  }  

}  

  

正如大家看到的那样,服务器对象的实现是非常简单的;它是一个普通的 Java 类,从 IDL 编译器生成的 

 “干”代码中继承而来。但在与ORB 以及其他CORBA 服务进行联系的时候,情况却变得稍微有些复杂。  

  

4。 一些CORBA 服务  

这里要简单介绍一下JavaIDL 相关代码所做的工作(注意暂时忽略了CORBA 代码与不同厂商有关这一事 

实)。main()的第一行代码用于启动 ORB。而且理所当然,这正是服务器对象需要同它进行沟通的原因。就 

在ORB 初始化以后,紧接着就创建了一个服务器对象。实际上,它正式名称应该是“短期服务对象”:从客 

户那里接收请求,“生存时间”与创建它的进程是相同的。创建好短期服务对象后,就会通过ORB 对其进行 

注册。这意味着ORB 已知道它的存在,可将请求转发给它。  

到目前为止,我们拥有的全部东西就是一个timeServerObjRef——只有在当前服务器进程里才有效的一个对 

象引用。下一步是为这个服务对象分配一个字串形式的名字。客户会根据那个名字寻找服务对象。我们通过 

命名服务(Naming Service)完成这一操作。首先,我们需要对命名服务的一个对象引用。通过调用 

resolve_initial_references(),可获得对命名服务的字串式对象引用(在JavaIDL 中是 

 “NameService”),并将这个引用返回。这是对采用narrow()方法的一个特定NamingContext 引用的模 

型。我们现在可开始使用命名服务了。  

为了将服务对象同一个字串形式的对象引用绑定在一起,我们首先创建一个Nameponent 对象,用 

 “ExactTime”进行初始化。“ExactTime”是我们想用于绑定服务对象的名称字串。随后使用rebind()方 

法,这是受限于对象引用的字串化引用。我们用rebind()分配一个引用——即使它已经存在。而假若引用已 

经存在,那么bind()会造成一个异常。在CORBA 中,名称由一系列NameContext 构成——这便是我们为什么 

要用一个数组将名称与对象引用绑定起来的原因。  



                                                                                         669 


…………………………………………………………Page 671……………………………………………………………

服务对象最好准备好由客户使用。此时,服务器进程会进入一种等候状态。同样地,由于它是一种“短期服 

务”,所以生存时间要受服务器进程的限制。JavaIDL 目前尚未提供对“持久对象”(只要创建它们的进程 

保持运行状态,对象就会一直存在下去)的支持。  

现在,我们已对服务器代码的工作有了一定的认识。接下来看看客户代码:  

  

import R
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!