1. 术语
每一种计算技术都会随着它的发展,创造出自己的词汇,Ice也不例外。然而,Ice使用新的术语数量很少;我们不是发明新的术语,而是尽可能地使用现有的术语。 如果你以前使用过其他中间件,你将会熟悉以下大部分内容。 (建议至少要快速的浏览一遍材料,因为Ice与其他中间件,还是存在少量术语上的差别。)
本页包含:
- 客户端与服务端
- Ice对象
- 代理
- 字符串化代理
- 直接代理
- 间接代理
- 间接绑定与直接绑定的区别
- 固定代理
- 路由代理
- 复制
- 副本组
- 服务(Servants)
- 最多一次语法(At-Most-Once Semantics)
- 同步方法调用
- 异步方法调用
- 异步方法调度
- 单向方法调用
- 批量单向方法调用
- 报文式调用(Datagram Invocations)
- 批量报文式调用(Batched Datagram Invocations)
- 运行时异常
- 用户异常
- 属性
1.1. 客户端与服务端
客户端和服务端不是某个应用程序特定部分的固定名称;相反,它们表示在请求期间,应用程序的某些部分所采用的角色:
- 客户端是主动实体, 他们向服务端发出服务请求。
- 服务端是被动实体, 他们提供服务来响应客户端请求。
通常情况下,服务端不是“纯粹的”服务端,因为它们从不发出请求,只响应请求。 相反,服务端通常代表某个客户端充当服务端,而又充当另一个服务端的客户端以满足客户端的请求。
同样,客户端往往也不是“纯粹的”客户端,因为他们只是一个对象的请求服务。 相反,客户端经常是客户端与服务端的混合。 例如,客户端可能会在服务端上启动一个长时间运行的操作;作为启动操作的一部分,客户端可以端提供一个回调对象
给服务端,用于当操作完成时,服务端去通知客户端。 在这种情况下,客户端在开始操作时充当客户端,在通知操作完成时作为服务端。
这种角色颠倒常见在很多系统中,所以,客户端系统与服务端系统经常可以被更准确地描述为对等系统(peer-to-peer systems )。
1.2. Ice对象
一个Ice对象是一个概念实体或抽象定义。 一个Ice对象可以用以下几点描述:
- Ice对象是本地或远程地址空间中的一个实体,可以响应客户端的请求。
- 单个Ice对象可以在单个服务端中实例化,或者冗余地在多个服务端中实例化。如果一个对象有多个相同的实例,它仍然是一个单独的Ice对象。
- 每个Ice对象都有一个或多个接口。接口是通过对象来支持已经命名方法的集合。客户通过调用方法发出请求。
- 一个方法有零个或多个参数以及一个返回值。参数和返回值有一个特定的类型。参数被命名并有一个方向:传入的参数被客户端初始化并传递给服务器;传出的参数由服务器初始化并传递给客户端。(返回值是一个特殊的输出参数。)
- 一个Ice对象有一个与众不同的接口,被称为主接口(main interface)。另外,一个Ice对象可以提供零个或多个可选接口,称为构面(facets)。客户端可以从一个对象的多个构面中选择它想要的接口。
- 每个Ice对象都有一个唯一的对象ID(object identity)。一个对象的ID是一个识别值,将不同的对象区分开来。Ice对象模型假定对象ID是全局唯一的,也就是说,Ice通信域中不能有两个对象是同一个ID。
实际上,你不需要使用全球唯一的对象标识(例如UUID),而只需要使用不会有冲突的标识在你的域中。当然,使用全球唯一的标识符有结构体系上的优势,我们会在对象的生命周期中讨论。
1.3. 代理
客户端想要访问Ice对象,这个客户端必须拥有一个Ice对象的代理。 代理是一个项目在本地客户端的地址空间;它代表客户端的(也可能是在远端)Ice对象。 代理充当Ice对象的本地大使:当客户端调用代理的操作时,Ice会做以下事情:
- 找到Ice对象
- 如果它没有运行,激活Ice对象的服务端
- 激活服务端内的Ice对象
- 将任何传入的参数传递给Ice对象
- 等待操作完成
- 将任何传出的参数和返回值返回给客户端(或者在错误的情况下抛出异常)
代理封装了需要完成这个操作步骤的所有信息。 特别是,代理包含:
- 地址信息,允许客户端运行时连接到正确服务端
- 一个对象ID,辨别目标请求在服务端中的对象
- 一个可选的构面标识符,区分一个对象中某个构面所指的代理
1.4. 字符串化代理
代理中的信息可以用一个字符串表示。 例如,SimplePrinter:default -p 10000
是以人类可读方式表示一个代理。 Ice运行时提供了API调用,允许你将代理转换为它的字符串形式,反之亦然。 这样做的好处是,可以将代理存储在数据库或文本中。
提供一个客户知道的Ice对象ID和它的寻址信息,它就可以通过提供的信息来“无中生有”地创建一个代理。 换句话说,代理内任何信息都可以被认为不透明;客户端只需要知道对象的ID,地址信息和(为了能够调用一个功能)对象的类型以便访问对象。
1.5. 直接代理
直接代理是把代理嵌入到对象的ID里,与地址一起在它的服务端里运行。 地址完全由以下指定:
- 一个协议标识符(如TCP / IP或UDP)
- 一个协议特定的地址(例如主机名和端口号)
为了访问由直接代理表示的对象,Ice运行时使用代理中的地址信息来访问服务端;对象的ID被发送到服务端与客户端的每个请求。
1.6. 间接代理
间接代理有两种形式。 一种是仅提供对象的ID,另一种是指定一个ID和一个对象适配器标识符一起。 只能使用ID访问的对象称为知名对象(well-known object)
,相应的代理是知名代理
。 例如,字符串:SimplePrinter
是ID为SimplePrinter的一个知名对象的有效代理。
一个包含对象适配器标识符的间接代理,用字符串格式写为:SimplePrinter@PrinterAdapter
对象适配器内的任何对象都可以使用这样的代理来访问,无视对象是否为知名对象。
请注意,间接代理不包含地址信息。 为了访问到正确的服务端,客户端运行时将代理信息传递给位置服务。 反过来,位置服务使用对象ID或对象适配器标识符,作为包含服务端地址查询表中的键,将查询到当前服务端的地址返回给客户端。 客户端运行时就知道如何访问服务端,并以普通方式来分发客户端请求。
整个过程与域名服务(DNS)工作原理相似:当我们使用域名(如www.zeroc.com)查找网页时,主机名是最先被解析为一个绑定的IP,一旦确认IP,就用IP连接到服务器。 使用Ice,映射是从对一个象ID或对象适配器标识符到一个协议的地址对。客户端运行时知道如何通过配置去访问位置服务(就像Web浏览器知道通过配置去访问DNS服务器一样)。