ice demo

----------------------------------------------转-------------------------

1、ICE是什么?
 ICE是ZEROC的开源通信协议产品,它的全称是:The Internet Communications
Engine,翻译为中文是互联网通信引擎,是一个面向对象的中间件,使我们能够以最小的代价构建分布式应用程序。ICE使我们专注于应用逻辑的开发,它来处理所有底层的网络接口编程,这样我们就不用去考虑这样的细节:打开网络连接、网络数据传输的序列化与反序列化、连接失败的尝试次数等。

2、为什么会有ICE? 
 ICE是分布式应用的一种比较好的解决方案,虽然现在也有一些比较流行的分布式应用解决方案,如微软的.NET(以及原来的DCOM)、CORBA及WEB
SERVICE等,但是这些面向对象的中间件都存在一些不足:
 .NET是微软产品,只面向WINDOWS系统,而实际的情况是在当前的网络环境下,不同的计算机会运行不同的系统,如LINUX上面就不可能使用.NET;
 CORBA虽然在统一标准方面做了很多的工作,但是不同的供应商实现之间还是缺乏互操作性,并且目前还没有一家供应商可以针对所有的异种环境提供所有的实现支持,且CORBA的实现比较复杂,学习及实施的成本都会比较高;
 WEB
SERVICE最要命的缺点就是他的性能问题,对于要求比较高的行业是很少会考虑WEB
SERVICE的。
 ICE的产生就是源于.NET、CORBA及WEB
SERVICE这些中间件的不足,它可以支持不同的系统,如WINDOWS、LINUX等,也可以支持在多种开发语言上使用,如C++、C、JAVA、RUBY、PYTHON、VB等,服务端可以是上面提到的任何一种语言实现的,客户端也可以根据自己的实际情况选择不同的语言实现,如服务端采用C语言实现,而客户端采用JAVA语言实现,底层的通讯逻辑通过ICE的封装实现,我们只需要关注业务逻辑。

3、ICE是如何工作的?
 Ice 是一种面向对象的中间件平台,这意味着 Ice为构建面向对象的客户-服务器应用提供了工具、API
和库支持。要与Ice持有的对象进行通信,客户端必须持有这个对象的代理(与CORBA的引用是相同的意思),这里的代理指的是这个对象的实例,ICE在运行时会定位到这个对象,然后寻找或激活它,再把In参数传给远程对象,再通过Out参数获取返回结果。
 这里提到的代理又分为直接代理和间接代理,直接代理其内部保存有某个对象的标识,以及它的服务器的运行地址;间接代理指的是其内部保存有某个对象的标识,以及对象适配器名(object
adapter
name),间接代理没有包含寻址信息,为了正确地定位服务器,客户端在运行时会使用代理内部的对象适配器名,将其传给某个定位器服务,比如IcePack服务,然后,定位器会把适配器名当作关键字,在含有服务器地址的表中进行查找,把当前的服务器地址返回给客户,客户端
run time现在知道了怎样联系服务器,就会像平常一样分派
(dispatch)客户请求。
 ICE可以保证在任何的网络环境或者操作系统下,成功的调用只有一次,它在运行时会尽力的定位到远程服务器,在连接失败的情况下会做尝试性重复性连接,确实连不上的情况会给用户以提示。
 客户端在调用服务端的方法时,可以采取同步或异步的方式实现,同步调用就相当于调用自己本地的方法一样,其它行为会被阻塞;异步调用是非常有用的调用方式,如服务端需要准备的数据来自于其它异步接口,这个时候客户端就不需要等待,待服务端数据准备充份后,以消息的方式通知客户端,服务端就可以去干其它的事情了,而客户端也可以到服务端获取数据了。
 
4、ICE调用模式
 ICE采用的网络协议有TCP、UDP以及SSL三
种,不同于WebService,ICE在调用模式上有好几种选择方案,并且每种方案正对不同的网络协议的特性做了相应的选择。
 Oneway(单向调用):客户端只需将调用注册到本地传输缓冲区(Local
Transport
Buffers)后就立即返回,不会等待调用结果的返回,不对调用结果负责。
 Twoway(双向调用):最通用的模式,同步方法调用模式,只能用TCP或SSL协议。
 Datagram(数据报):类似于Oneway调用,不同的是
Datagram调用只能采用UDP协议而且只能调用无返回值和无输出参数的方法。
 BatchOneway(批量单向调用):先将调用存
在调用缓冲区里面,到达一定限额后自动批量发送所有请求(也可手动刷除缓冲区)。
 BatchDatagram(批量数据报):与上类似。
 不同的调用模式其实对应着不动的业务,对于大部分的有返回值的或需要实时响应的方法,我们可能都采用Twoway方式调用,对于一些无需返回值或
者不依赖返回值的业务,我们可以用Oneway或者BatchOneway方式,例如消息通知;剩下的Datagram和BatchDatagram方式
一般用在无返回值且不做可靠性检查的业务上,例如日志。

5、客户端与服务端的结构
 
 这个图示显示了使用ICE做为中间件平台,客户端及服务端的应用都是由应用代码及ICE的库代码混合组成的。
 客户应用及服务器应用分别对应用的是客户端与服务端。
 代理是根据SLICE定义的ice文件实现,它提供了一个向下调用的接口,提供了数据的序列化与反序化。
 ICE的核心部份,提供了客户端与服务端的网络连接等核心通信功能,以及其它的网络通信功能的实现及可能的问题的处理,让我们在编写应用代码的时候不必要去关注这一块,而专注于应用功能的实现。
 
6、ICE的简单示例
 要使用ICE,必须先安装ICE,安装及配置参考如下:
 WINDOWS:http://blog.csdn.net/fenglibing/archive/2011/04/28/6368665.aspx
 LINUX(BDB的安装还有问题,无法使用SLICE2JAVA):http://blog.csdn.net/fenglibing/archive/2011/04/27/6367559.aspx
 这个示例是JAVA示例,是从ICE的帮助文档中摘出来的,是一个输出Hello
World的测试程序,采用的ICE版本是3.1.1。
 1)、准备一个ice文件并命名为:Printer.ice,其内容为:

?





1

2

3

4

5

module Demo {

interface
Printer {

void printString(string
s);

};

};

  

2)、转到命令行,在Printer.ice文件保存目录执行命令:
  slice2java
Printer.ice
 会在目录下面生成一个Demo 文件夹,里面会生成一些JAVA文件,如下图示:

3)、这些文件的类图结构如下:

这里对生成的一些文件做些解释,分两两部份,服务端类文件及客户端类文件:
 ?
<interface-name>.java
 这个源文件声明在ICE文件中定的接口名称的Java接口,如这里是Printer。
 ?
_<interface-name>Operations.java
 _<interface-name>OperationsNC.java
 这是两个定义操作的接口文件,每个接口文件中定义了一个操作实现,定义的操作与Slice接口中定义的操作相一致,只是在_<interface-name>Operations.java中定义的方法多了一个参数“Ice.Current
__current”(注:Current对象的定义,请参见3.1.1版本文档中的31.6 The Ice::Current
Object说明),这个参数的作用是可以允许我们访问 “正在执行的请求”和
“服务器中的操作的实现”等信息,也就是我们的请求需求需要其它请求的支持时或者要获取其它请求的执行结果时,我们可以调用这个方法,这两个接口文件都会被接口文件_<interface-name>.java继承。
 ? 
_<interface-name>Disp.java
这个文件包含的是服务器端骨架类的定义,所用接口定义都要继承这个东西,这里的接口指供客户端调用的接口。
 ?
<interface-name>PrxHolder.java 代理定义holder
类,是对应Out参数使用的。一般参数都是值传递,这个类的作用是使参数通过引用传递。ICE框架应用了很多反射机制,这个类是改变远程参数的一个映射。
 
 
? _<interface-name>Del.java
  ?
_<interface-name>DelD.java
  ?
_<interface-name>DelM.java
 不用关心上面的这些文件,这些文件包含的是供Java
映射内部使用的代码;它们包含的功能与应用程序无关。
 ? <interface-name>Prx.java
这个是代理接口。例如PrinterPrx,在客户的地址空间中, PrinterPrx
的实例是“远地的服务器中的Printer接口的实例”的“本地大使”。与服务器端对象有关的所有细节,比如其地址、所用协议、对象标识,都封装在该实例中。
 注意,
PrinterPrx 继承自Ice.ObjectPrx。这反映了这样一个事实:所有的Ice
接口都隐式地继承自Ice::Object。
 说的更明白些,就是这个类的方法调用都是远程服务端的调用,执行printString()方法的具体实现是在远程服务端执行的。
 ?
<interface-name>PrxHelper.java
这个是接口的代理定义助手类,就是帮你获得代理类的。经常用的就两个方法checkedCast 和 uncheckedCast
。这两个方法实现的都是向下转换。
 注意, checkedCast
会联系服务器。这是必要的,因为只有服务器情况中的代理实现确切地知道某个对象的类型。所以, checkedCast
可能会抛出ConnectTimeoutException
或ObjectNotExistException(这也解释了为何需要助手类:ICE在运行时必须联系服务器,所以我们不能使用Java
的向下转换)。
 与此相反, uncheckedCast 不会联系服务器,而是会无条件地返回具有所请求的类型的代理
。但是,如果你要使用uncheckedCast,你必须确定这个代理真的支持你想要转换到的类型;而如果你弄错了,你很可能会在调用代理上的操作时,引发运行时异常。对于这样的类型失配,最后可能会引发OperationNotExistException,但也有可能引发其他异常,比如整编异常。而且,如果对象碰巧有一个同名的操作,但参数类型不同,则有可能根本不产生异常,你最后就会把调用发送给类型错误的对象;这个对象可能会做出非常糟糕的事情。
 
 4)、建立一个ECLIPSE工程,将生成的文件拷贝到src目录下,并在classpath中导入Ice.jar。
 5) 、建立三个测试JAVA文件,Server.java、PrinterI.java及Client.java:
 PrinterI.java是对服务端实现骨架类_PrinterDisp的实现,返回时将PrinterI.java对象返回给客户端,这里实现的功能是直接输出传入的String参数:

?





1

2

3

4

5

public
class PrinterI extends Demo._PrinterDisp {

    public
void printString(String s, Ice.Current current) {

        System.out.println(s);

    }

}

  

Server.java是服务端服务代理,用于接收客户端的请求操作:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

public
class Server {

    public
static void main(String[] args) {

        int
status = 0;

        Ice.Communicator ic = null;

        try
{

            //初使化连接,args可以传一些初使化参数,如连接超时时间,初使化客户连接池的数量等

            ic = Ice.Util.initialize(args);

            //创建名为SimplePrinterAdapter的适配器,并要求适配器使用缺省的协议(TCP/IP侦听端口为10000的请求)

            Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");

            //实例化一个PrinterI对象,为Printer接口创建一个服务对象

            Ice.Object object
= new
PrinterI();

            //将服务单元增加到适配器中,并给服务对象指定名称为SimplePrinter,该名称用于唯一确定一个服务单元

            adapter.add(object, Ice.Util.stringToIdentity("SimplePrinter"));

            //激活适配器,这样做的好处是可以等到所有资源就位后再触发

            adapter.activate();

            //让服务在退出之前,一直持续对请求的监听

            ic.waitForShutdown();

        } catch
(Ice.LocalException e) {

            e.printStackTrace();

            status = 1;

        } catch
(Exception e) {

            System.err.println(e.getMessage());

            status = 1;

        }

        if
(ic != null) {

            // Clean up

            //

            try
{

                ic.destroy();

            } catch
(Exception e) {

                System.err.println(e.getMessage());

                status = 1;

            }

        }

        System.exit(status);

    }

}

  

Client.java是客户端代码,用于向服务端发起请求,并操作返回的代理对象:

?





1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

public
class Client {

    public
static void main(String[] args) {

        int
status = 0;

        Ice.Communicator ic = null;

        try
{

            //初使化

            ic = Ice.Util.initialize(args);

            //传入远程服务单元的名称、网络协议、IP及端口,获取Printer的远程代理,这里使用的stringToProxy方式

            Ice.ObjectPrx base
= ic.stringToProxy("SimplePrinter:default -p 10000");

            //通过checkedCast向下转换,获取Printer接口的远程,并同时检测根据传入的名称获取的服务单元是否Printer的代理接口,如果不是则返回null对象

            Demo.PrinterPrx printer = Demo.PrinterPrxHelper.checkedCast(base);

            if
(printer == null) throw
new Error("Invalid proxy");

            //把Hello World传给服务端,让服务端打印出来,因为这个方法最终会在服务端上执行

            printer.printString("Hello World!");

        } catch
(Ice.LocalException e) {

            e.printStackTrace();

            status = 1;

        } catch
(Exception e) {

            System.err.println(e.getMessage());

            status = 1;

        }

        if
(ic != null) {

            // Clean up

            //

            try
{

                ic.destroy();

            } catch
(Exception e) {

                System.err.println(e.getMessage());

                status = 1;

            }

        }

        System.exit(status);

    }

}

  

6)、运行客户端和服务端
 运行服务端:java Server
 运行客户端:java
Client
 看看效果吧。

7、ICE的性能和效率
 ICE的性能是比较好的,因为他本身的传输机制都是基于二进制,网上有人曾经做过性能测试,评价比较好,我本人还没有做性能测试,目前的判断只是基于网络数据,请先看下面的文章:
 高性能计算-ICE
性能测试
 ICE与CORBA比较的优势
 
8、ICE的优点
支持同步和异步的消息传递;
支持多个接口;
机器无关性,客户及服务器与底层的机器架构屏蔽开来。对于应用代码而言,像字节序和填充这样的问题都隐藏了起来;
语言无关性,客户和服务器可以分别部署,所用语言也可以不同;
实现无关性,客户不知道服务器是怎样实现其对象的。这意味着,在客户部署之后,服务器的实现可以改变;
操作系统无关性,Ice
API 完全是可移植的,所以同样的源码能够在 Windows和 UNIX
上编译和运行;
线程支持,Ice run time 完全是线程化的,其
API 是线程安全的,作为应用开发者,(除了在访问共享数据时进行同步)无需为开发线程化的高性能客户和服务器付出额外努力。
传输机制无关性,Ice
目前采用了TCP/IP 和 UDP作为传输协议。客户和服务器代码都不需要了解底层的传输机制;
位置和服务器透明性,Ice run time
会负责定位对象,并管理底层的传输机制,比如打开和关闭连接;
安全性,通过
SSL强加密,可以使客户和服务器完全安全地进行通信,这样,应用可以使用不安全的网络安全地进行通信,你可以使用
Glacier穿过防火墙,实现安全的请求转发,并且完全支持回调;
内建的持久机制,使用
Freeze,创建持久的对象实现变成了一件很容易的事情,Ice提供了对高性能数据库 Berkeley DB[18] 的内建支持;
开放源码。

后记
这里只是简单的对ICE进行介绍,还有很多东西没有提到,如ICE的语法规则、ICE的版本控制(Facet)、持久化 (Feeze)、服务装箱管理
(ICEBox)、文件分发(ICEPatch2)、发布/订阅
服务(ICEStorm)、网络拓扑负载解决方案--终极武器(ICEGrid)、提供使用安全传输入协议SSL的插件(IceSSL)、轻量级的ICE应用防火墙其解决方案(Galcier2),这些留待大家后面去学习了。

时间: 2024-08-07 11:25:02

ice demo的相关文章

ICE安装及使用示例

ICE是什么 ZeroC ICE 是指ZeroC公司的ICE(Internet Communications Engine)中间件平台. Ice 应用适合于异构平台环境中使用:客户和服务器可以采用不同的编程语言,可以运行在不同的操作系统和机器架构上,并且可以使用多种网络技术进行通信.无论部署环境如何,这些应用的源码都是可移植的. 其采用C/S 模式结构,支持同步调用方式和异步调用方式,异步派发调用方式.支持跨语言的对象调用.多种语言之间采用共同的Slice(Specification Langu

在python中实现基于ICE框架的client、server模型

ICE (Internet Communication Engine) 是zeroc公司实现的通信中间件 几大特性: 1. 多语言支持C++.Java.python, C#等, 2.  对分布式系统的支持,涵盖了负载均衡.位置服务.计算节点需要实时启动等特性. 3.  提供了基于发布-订阅机制的消息组建ICEStorm 一.书写slice文件,然要按照slice规定的语法来实现 Printer.ice 1 2 3 4 5 module Demo {     interface Printer {

ICE中间件介绍以及demo

一:基本开发步骤 根据业务编写slice:写任何ICE应用的第一步都要编写一个slice定义,其中包含了这个应用的所有接口 编写实现接口代码:命名规则就是接口的名字加上I 编写server端代码 写配置文件,部署服务 编写client端代码 先启动server端服务,然后启动client端服务 二:demo(安装ice服务) 定义一个接口,建立一个Printer.ice文件 moudle Demo{     interface Printer{ void printString(string s

ICE提纲之demo/IceStorm/clock

ICE发布者/订阅者的一个最简单例子 IceStorm服务 config.icebox # # The IceBox server endpoint configuration. This endpoint is only used # to communicate with the IceBox ServiceManager object (such as when # using iceboxadmin to shutdown the server). # # The IceStorm se

ICE提纲之demo/Glacier2/callback

本例子展示了Glacier2 router的用法(没有使用Glacier2 session manager). 如果clients与router不在同一台主机上,需要将以下地方修改为glacier2router所在机器的外部地址: config.glacier2的Glacier2.Client.Endpointsconfig.client的Ice.Default.Router和Callback.Client.Router Glacier2router服务 启动命令 $ glacier2route

ICE分布式文件管理系统——ICE环境搭建(其二)

上一博文,我们讲述了ICE这个中间件的基本认识. 接下来我们讲述开发环境搭建. 其过程主要分为三步: 安装GCC-4.4.6.安装ICE-3.4.2.安装QT-4.7.3. (本文是基于LINUX下的ICE-3.4.2的安装,如果已安装了GCC(版本高于GCC-4.4.6亦可),请直接安装ICE) 一.安装GCC: (gcc各版本浏览地址:http://ftp.gnu.org/gnu/gcc/) 一般来说基于linux的操作系统都是默认安装了GCC的.假如说你的电脑没有的话 请百度一哈,可以解决

ICE中间件说明文档

1       ICE中间件简介 2       平台核心功能 2.1        接口描述语言(Slice) 2.2        ICE运行时 2.2.1         通信器 2.2.2         对象适配器 2.2.3         位置透明性 2.3        异步编程模型 2.3.1         异步方法调用 2.3.2         异步方法分派 2.4        订阅/发布编程模型 2.5        动态服务管理(IceBox) 2.6       

opensuse x64下编译Ice源码(以编译c++为例)

官方编译文档见Ice官方编译文档 环境: opensuse13.1 x64,kdevelop4.7.6 ICE依赖包: Ice has dependencies on a number of third-party libraries: Berkeley DB 5.3 expat 2.0 OpenSSL 0.9.8 or later bzip2 1.0 mcpp 2.7.2 (with patches) 依赖包安装: zypper install mcpp mcpp-devel openssl

The Internet Communications Engine (Ice) 跨平台异构通讯方案 第一弹-ICE简介

.net中的通讯方案很多,从.net Remoting,MSMQ,Webservice,WSE,WCF等等,他们都有一个特点,易用,但是都不能跨语种异构,如果你服务端要用java开发,客户端用C#开发,或者其它语言譬如C++, Python,PHP, Ruby, Objective-C,等等,那么.net提供的解决方案将不再有效.现在,隆重推出跨平台异构方案ICE.ICE官网:http://www.zeroc.com/ice.html 简介:The Internet Communications