7 月,我们创建了一个简单示例 -- SimpleCalc。这个示例不值得多说;它是单一方法 add() ,接受两个 IDL long 型变量,返回一个 long 型变量。讲授与学习 CORBA 的一个难题是:已知它是基于分布的客户机和服务器,从一开始它就变得很复杂。必须立即与网络打交道。所以,让我们现在就来谈谈网络。
如
果将话题深入一点,将发现许多都值得探讨,但又很简单。我们简单的计算器服务器设计成被远程调用,CORBA
专门确保让我们不必担心客户机环境和服务器环境之间的差异。客户机对服务器的远程调用是根据远程过程调用 (RPC) 协议生成的,该协议自 20
世纪 80 年代就存在。RPC 是由各种通信模型经过多年测试得到的结果 -- 这是已经在产品环境中测试过的可靠且真实的技术。我们现在使用的
CORBA 模型就基于该模型。
|
让我们跟踪方法调用。客户机必须首先获得计算器的实例。它通过使用 calculatorHelper.java narrow() 方法来达到这一目的。
ior 是可互操作对象引用 (IOR) 的字符串表示,是从文件
calcref.ior 中检索到的。这个文件是由服务器写的,以便客户机可以定位并连接到它。对 orb
string_to_object() 的方法调用只取得
ior 字符串,并将它转换成对象引用。以下是客户机中的代码,
SimpleCalcClient.java :
calculator calc = calculatorHelper.narrow(orb.string_to_object(ior)); |
IOR 中有什么?IOR 是一个数据结构,它提供了关于类型、协议支持和可用 ORB 服务的信息。ORB 创建、使用并维护该 IOR。许多 ORB 供应商提供了一个实用程序来窥视 IOR 的内部。OOC (Object Oriented Concepts, Inc.) 的 Orbacus(请参阅 参考资料) 附带 IORDump.exe,如果您使用 Visibroker,它为您提供了 PrintIOR.exe。也有一些网站为您分析 IOR;可在 Xerox Parc 站点(请参阅 参考资料)上找到我使用的一个实用程序。因为正在使用 Orbacus,我将对在 SimpleCalc 示例中创建的 IOR 运行 IORDump。得到以下输出:
C:\_workcorbasem\_sourcescalcsimpl>iordump -f calcref.ior |
IOR 中嵌入的是 type_id、IIOP 版本、主机地址和端口号,以及对象键。type_id 字符串是接口类型,众所周知,它是 资源库标识格 式。基本上,资源库标识是接口唯一的标识。这个标识可以是 DCE UUID 格式(COM 程序员比较熟悉它)或者是您指定的本地格式。IIOP 版本将帮助 IOR 阅读器(通常是 ORB)正确了解 IOR 是哪种格式,因为 OMG 总是改进规范,每个版本的阅读方法都与以前版本略有不同 ;-)。主机地址和端口号将让我们接触到与期望的对象通信的 ORB。对象键和许多其它资料都是按特定于服务的信息的 OMG 标准构建的。这是帮助 OTB 支持服务器的特定于服务的数据。例如,这些专用 IOR 组件可以编码 ORB 类型和版本,或者帮助支持 OMG 安全服务的 ORB 实现。以上大多数信息指定了字符代码集转换,这样客户机和服务器就能够互相理解。
如果通过 Xerox Parc IOR 语法分析器运行 IOR,将得到以下输出:
IIOP_ParseCDR: byte order BigEndian, |
IOR 中最主要的部分是帮助客户机连接到服务器的那些部分。可以在 Xerox Parc IOR 阅读器(请参阅 参考资料)的输出中看到这些部分。但是,其它许多信息是 Orbacus 专有的,其它 IOR 阅读器不能解释它。这些专用部分是作为附加到 IOR 的数据序列出现的,并且只有构建 IOR 的 ORB 才懂得这些数据。
|
现
在,我们知道 IOR 带来了什么功能。IOR 的目的就是使客户机能够连接到服务器,以便它能够完成方法调用。客户机必须用 Add 方法将 IOR
转换成它可以调用的实际对象。这是通过使用从 IDL 编译器中生成的两个 Java 文件来完成的。客户机将首先使用
calculatorHelper 对象将 IOR 的范围缩小到 _calculatorStub 代理对象。
以下是 Orbacus 附带的 jidl 编译器生成的 narrow() 方法:
public static calculator narrow(org.omg.CORBA.Object _ob_v) { |
可以看到,它最主要的任务是创建一个新的 _calculatorStub 对象。 _calculatorStub 充当驻留在服务器上的实际计算器对象的代理对象。如果您不了解代理模式,我将非常乐意向您介绍“四人组” Design Patterns一书(请参阅 参考资料)。实际上,代理模式无非是创建一个代表或充当另一个实际对象的替身的对象,另一个对象将最终将调用或执行服务。代理模式是一种重要且常用的模式。在所有分布式设计中都会用到它。我敢打赌,您肯定用过这种模式,只不过从没有称您的设计为代理模式。
一旦创建了 _calculatorStub ,它就代表客户机的计算器接口。add 方法在服务器中实现,而该服务器在 IOR 中定义的地址上的电脑空间中运行。至此,这就所调用的 add() 方法。这里,需要注意两点:首先,我们必须以 _calculatorStub 的形式调用 add 方法。其次,请注意客户机将中断直到调用返回,就像其它同步方法调用一样。这是一种请求响应协议,它模仿单进程应用程序。编程客户机,然后使用该请求响应 协议执行客户机就像用库和 API 调用创建的常用编程开发环境一样普通自然。这并不表示您不能使用异步调用;您当然可以生成那种类型的调用。我将在以后的专栏文章中讨论那些话题。
|
至
此,在体系结构中,我们已成功欺骗了客户机,使它相信服务与它在一起。但事实并为如此,并且在以后几步中,我们必须将数据和方法调用铸造成一种形式,它允
许在网络上继续该调用,并且可以在另一端使用该调用。这并不是无关重要的,且这种模型已经问世好几年了。您也许已经多次见过 OSI 模型了,在图 2
中,您将看到 OSI 模型,旁边就是 OMG 所使用的模型。
现在,我们应当窥视 _calculatorStub 生成的代码的内部信息。请记住这不是由我编写的 -- 它是由 Orbacus 附带的 IDL-到-Java 编译器 jidl 生成的。
// |
公共数据表示 (CDR)
公共数据表示 (CDR) 是
CORBA
调用中将使用的数据类型的正式映射。客户机生成请求时,它不必知道请求要发送到什么地方,或者哪一台服务器将响应该请求。CORBA(作为规范)和
GIOP(作为规范的一部分,定义消息结构和传送)被设计成允许实现一个接口的可能的多种不同服务器之一来响应请求。规范必须定义如何打包操作中的数据,
这样所有可能的服务器都可以抽取参数并调用远程操作,并且数据转换不会产生多义性。这种转换问题的典型示例就是指针。客户机中的指针对于在另一台机器上运
行另一个进程的服务器意味着什么?毫无意义。或者,变量如何在使用不同寻址方案(大尾数法,小尾数法)的机器间发送?这些数据类型必须转换成服务器能够理
解并使用的流。显然,CORBA 规范在公共数据表示方面是十分详细的。这是我们不必涉足的细节层次,但如果您想要了解详细信息,请阅读规范或
Ruh、Herron 和 Klinkeron 合著的 IIOP Complete一书(请参阅
参考资料)。
一 旦包装了所有数据,就将使用 IOR 中的信息来创建连接。您可以区别 IOR 的结构,通常必须使用 TCP 作为传送机制。但是,也可以使用其它传送(再次提醒,请参阅 CORBA 规范以获取详细信息)。ORB 守护程序负责查找 IOR 指定的对象实现,以及建立客户机和服务器之间的连接。一旦建立了连接,GIOP 将定义一组由客户机用于请求或服务器用于响应的消息。客户机将发送消息类型 Request、LocateRequest、CancelRequest、Fragment 和 MessageError。服务器可以发送消息类型 Reply、LocateReply、CloseConnection、Fragment 和 MessageError。
如果我们扯开 GIOP 消息,它看上去就像:
0x47 0x49 0x4f 0x50 -> GIOP, the key |
您 应该了解大概情况了。这种消息流是高度结构化的。它也必须是,为了客户机可以创建服务器可以转换成实现的消息 -- 不管实现如何运行,或在哪里运行。服务器也必须为在响应客户机时使用的返回值和参数执行相同操作。此消息格式在 OMG 成就中非常重要,因为它可以实现可移植性和互操作性目标。这种可移植性将给予您我们在第一篇专栏文章中谈到的自由。您无需关心硬件、数据库或编程语言。只 要关心您的信息就行了。
|
我
们还没有彻底结束。GIOP 是 CORBA 方法调用的核心部分。GIOP 不基于任何特别的网络协议,如 IPX 或
TCP/IP。为了确保互操作性,OMG 必须将 GIOP
定义在所有供应商都支持的特定传输之上。如果有详细和简洁的消息规范,则不会提供互操作性,因为所有供应商使用不同的传送机制来实现这个互操作性。因此,
OMG 在最广泛使用的通信传输平台 -- TCP/IP 上标准化 GIOP。GIOP 加 TCP/IP 等于 IIOP!就这么简单。
需要使用已发布对象服务的客户机将使用 IOR 中的值来启动与对象的连接。我们已经绕了一个圈子,又回到了 IOR。IOR 对于 IIOP 是至关重要的,任何要对某个对象调用方法的客户机都要将“请求”消息发送到 IOR 中详细说明的主机和端口地址。在主机上,服务器进程在请求进入时会侦听端口,并将那些消息发送到对象。这就要求服务器主动侦听请求。
生 活有阴阳两面,每件事都有缺点,互操作性和 IIOP 也不例外。OMG 推出和运行了 IIOP,对比 ORB 供应商它们自己的服务器上实现此功能,并且没有服务器方可移植性的年代,这是一大改进。但如果要求服务器是位置无关的,我们应该做什么?如果主机和端口值 嵌入 IOR 中,每当您将对象从一个服务器移到另一个服务器,以均衡负载时,这个问题就会突然出现。可喜的是这个问题已经解决了;但又有一条坏消息,每家供应商的解决 方法都不同。
|
现
在,将负载均衡话题留到将来讨论。如果您在几年前有
CORBA“经验”(也就是说在一段时期内),而现在从事另一项研究,我相信您将感到惊喜。CORBA 规范已经获得很大进步,可以确保您为一个
ORB 编写的服务器代码可以移植到运行另一个 ORB
的另一台服务器上。解决方案非常简单,并且以经典的协议为基础。客户机和服务器间的标准交换语法基于某些 OMG 详细说明的需求。OMG
通过使用网络寻址协议 (IIOP) 独立于消息传递协议
(GIOP),为其规范创建了更多功能。这也确保随着信息工业的变动(的确发展很快),CORBA
仍能跟上它的步伐。我最喜欢的是,对于我们刚讨论的关于如何使之成功完成的 CORBA 对象调用,我不必编写代码!在 ORB 中和用 IDL
标准化接口的功能中已经概括了网络测量和打包的详细信息。下个月,我们将讨论 IDL。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/374079/viewspace-130724/ ,如需转载,请注明出处,否则将追究法律责任。