ICE技术研究.docx
《ICE技术研究.docx》由会员分享,可在线阅读,更多相关《ICE技术研究.docx(29页珍藏版)》请在冰豆网上搜索。
ICE技术研究
ICE专题
ICE简介
ICE(InternetCommunicationsEngine)是一个为现实中程序员而写的中间件平台。
作为一个高性能的互联网通信平台,ICE包含了很多分层的服务和插件(Plug-ins),并且简单、高效和强大。
ICE的自由使用遵从GNU的GPL(GNUGeneralPublicLicens)许可的条款。
ICE也有商业的许可证,如果你想将ICE使用在你的私有产品中,那么你应该使用ICE的商业许可证。
可以联系sales@来获得这方面的更多信息。
ICE当前支持C++、Java、C#、VisualBasic、Python和PHP编程语言,并支持在多种操作系统上运行。
更多的操作系统和编程语言将会在以后的发布中支持。
ICE有以下几部分组成:
Slice
ICE的规范语言,跟CORBA的IDL(InterfaceDefinitionLanguage)等价的东西。
Slice建立了客户端和服务器端共同遵守的契约:
接口。
Slice也用来描述对象持久数据。
SliceCompilers
Slice的规范语言可以影射成多种编程语言。
目前ICE支持C++,Java,Python,PHP,C#和VB的语言影射。
Ice的客户端和服务器端协同工作,而不会知道分别实现的是何种编程语言。
Ice
Ice的核心库。
在众多的特性当中,Ice核心库通过一个高效的协议(包含TCP/UDP层上协议压缩)来管理所有的通信任务,为多线程服务器提供了一个灵活的线程池,并且有特别的功能来支持上百万对象的可扩展性。
IceUtil
一些常用的功能函数集。
例如Unicode处理和多线程编程,是用C++写成。
IceBox
一个专用于ICE应用的应用服务器。
ICEBox可以方便地运行和管理动态加载、共享库或java类的形式Ice的服务。
IcePack
一个成熟的服务激活和部署工具。
IcePack能大大简化在异构网络之间部署应用的复杂性。
只要简单的编写XML格式的一个部署描述文件,IcePack就能自动处理剩下的工作。
Freeze
Freeze提供了IceServants对象的自动持久性。
通过几行代码,一个应用就可以生成一个高度可扩展的逐出器(evictor)来高效地管理持久对象。
FreezeScript
在大的软件项目里,持久对象的数据类型改变很常见。
为了最小化这些变化的影响,FreezeScript提供了相应的工具来检查和移植Freeze生成的数据库。
这些工具支持XML格式的配置脚本,易于使用。
IceSSL
用于Ice核心的动态的SSL传输插件。
提供了认证、加密和消息完整性,使用工业标准的SSL协议来实现。
Glacier
面向对象中间件平台的一个最大的挑战是安全性和防火墙。
Glacier是Ice的防火墙解决方案,它大大简化了安全程序的部署。
Glacier认证和过滤客户的请求并允许服务器通过安全的方式回调客户端对象。
结合IceSSL的使用,Glacier提供了强大的安全解决方案,即安全,又易于配置管理。
IceStorm
一个支持联盟的消息服务。
和大多数的其他消息和事件服务相比,IceStorm支持有类型的事件,这意味着通过联盟广播一个消息和调用一个接口上的一个方法一样容易。
IcePatch
一个软件修补和分发的服务。
为确保运行的软件是最新的版本,要经常更新软件,这是一件乏味的工作。
IcePatch自动更新在某个目录层次下的文件。
只有需要更新的文件会下作到客户端,为了快速的下载更新,IcePatch使用的高效的压缩算法。
如想了解更多的详细信息,可以到上下载关于Ice的更多文档。
ICE在Linux下的安装
Ice的安装
从年初的一期《程序员》杂志上了解到ICE以后,因为其对比于CORBA具有简单、高效、易用的特点,所以一直都有留意。
之前也有一段时间下载了Ice1.x版本和相应的文档来研究,但因工作忙,中断了一段时间。
Ice的主页:
这几天工作稍微轻松点,有点时间,就继续研究Ice2.1.1版本。
在学习的过程中,免不了要安装的。
这篇文章就是想说说安装的问题。
其实Ice-2.1.1安装算是蛮简单的。
因为像比较新的Linux操作系统上,Ice所需的辅助软件包都已经有了,如果你装的系统确实没有这些软件,可以在Ice的下载页面上下载到第三方的软件包,然后安装,安装这些都不难,主要是要看软件相应的readme和install类型的文档。
我在Fedora3上安装,上面带了expat,openssl,db4.2,bzip2,所以基本不用装第三方的软件。
唯一一个问题是:
Fedora3上的db4.2没有安装db的C++开发库,所以需要重新编译安装db。
=========== STEP1:
安装db =============================
安装db的文档在db包的docs里面有html格式的说明文档,很简单。
解开db的tar/zip包后:
$cddb-ver
$cdbuild_unix
$../dist/configure--prefix=/usr--enable-cxx
$make
$su
#makeinstall
========== STEP2:
安装Ice2.1.1包 ====================
解开Ice-2.1.1.tar.gz包后
$cdIce-2.1.1
$viconfig/Make.rules #修改prefix为/usr
$make
$su
#makeinstall
这样Ice就安装好了。
========== STEP3:
安装IcePy============================
因为自己想结合之前学习python,刚好ice也支持python语言,所以决定安装IcePy包,如果你只用C++开发的话,IcePy可以不装。
解开IcePy.xx.tar.gz后
$cdIcePy-2.1.1
$viconfig/Make.rules
增加一行在文件的最前面:
ICE_HOME=/usr
修改prefix=/usr
然后用root权限
#ln-s/usr/lib/python2.4/usr/python #不同版本的python,/usr/lib/pythonx.x目录有点不同
$make
$su
#makeinstall
#ln-s/usr/lib/IcePy.so/usr/lib/python2.4/IcePy.so
至于用两个ln建立两个连接主要是省去运行Icepython程序的时候,设置环境变量的麻烦。
因为IcePython的文件都安装到了python的缺省目录下了,这样会方便很多。
附一个C++编译的问题:
由于我按照书上的例子来学习Ice,所以文件服务器的服务器端那章里面的NodeI类定义如下:
classNodeI:
virtualpublicNode{
public:
virtualstd:
:
stringname(constIce:
:
Current&)const;
NodeI(conststd:
:
string&,constDirectoryIPtr&parent);
staticIce:
:
ObjectAdapterPtr_adapter;
private:
conststd:
:
string_name;
DirectoryIPtr_parent;
NodeI(constNodeI&);
voidoperator=(constNodeI&);
};
里面有static的类成员_adapter,由于久未用C++,不记得要在.cpp实现文件里加:
Ice:
:
ObjectAdapterPtrFilesystem:
:
NodeI:
:
_adapter;
定义,所以g++连接老报没有定义_adapter的错误,郁闷了一段时间才记起来。
而书上的例子并没有提到定义这个东西,如果你是C++新手或像我这样久未用C++的人,一时还找不着北呢。
ICE起步
最早开始接触ICE是在2005,3月份,当时一个朋友向另一个正打算研究corba的朋友强烈的推荐了ICE.
参考:
1.什么是ICE?
ICE(internetcommunicationsengine)是适用于异种环境的面向对象中间件平台。
那么什么是中间件呢?
比较流行的定义是:
中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。
中间件位于客户机/服务器的操作系统之上,管理计算资源和网络通讯。
从中间件的定义可以看出,中间件是一类软件,而非一种软件;中间件不仅仅实现互连,还要实现应用之间的互操作;中间件是基于分布式处理的软件,定义中特别强调了其网络通讯功能.
(如此说来,twisted就是一个中间件)
目前中间件的三大主流平台:
1.OMG的CORBA
2.sun的J2EE(包括ejb等技术)
3.MS的MicrosoftDNA2000(DCOM/COM/COM+等技术)
关于中间件的介绍:
2.ICE的一些概念
∙服务器/客户端(server/client):
这个的定义与一般的定义相同,主动的一方被认为是client
∙ICE对象:
跟OOP中的对象类似,不同之处在于,在分布式的环境中,同一个ICE对象在不同的地址空间中都可能存在着.ICE对象也提供了一组接口(facets).ICE对象还有一个特殊的接口:
主接口.
∙代理(proxies):
是ICE对象引用,代理是在客户地址空间,客户对ICE对象的操作就是通过代理来进行的.代理封装了完成:
ICE对象的寻址(包括服务器的寻址),激活ICE对象,传入参数,等待执行并返回执行结果
∙servant:
在服务器上的执行体,ICE对象对服务器的操作就是通过调用servant.
∙"最多一次"原则:
一次对目的的访问,只会执行一次(并不排除出错重试)
ICE的5个服务
Summary这里介绍了ICE的五个服务
Ice为分布式开发提供了技术完善的客户-服务平台。
实际上,现实的应用不仅仅只需要具备远程通讯能力,通常的,还需要随需启动服务,把代理分布到客户端,分发异步事件,配置应用,发布补丁等等。
Ice自带了一些服务,这些服务具备了上面所说的特征和一些其它的特征。
这些服务实现以服务器的形式实现并向你的应用提供服务。
他们分别是:
1、IcePack
IcePack是Ice的定位服务。
当使用间接绑定时,用来将符号化的适配器名称转换为协议-地址对。
除了定位服务之外,IcePack还提供了如下的服务:
∙IcePack允许你注册一个自动启动的服务:
即当客户端进行请求时,服务器不需要处于运行状态,只要第一个客户端进行请求时,服务会自动启动。
∙IcePack支持脚本描述部署,可以轻易的配置包含了若干个服务的复杂的应用
∙IcePack提供了简单的对象查找服务,允许客户端获取他们感兴趣的对象代理。
2、IceBox
IceBox是一个简单的应用服务器,它可以协调多个应用组件启动和停止。
应用组件可以用动态链接库的形式发布而不是一个进程。
这就减轻了系统的负载。
例如,你可以在一个JVM中运行若干个应用组件而不是有多个进程,每一个进程都有自己的JVM。
3、IceStorm
IceStorm是一个发布-订阅服务,它减除了客户端和服务器的耦合度。
本质上说,IceStorm作为一个事件分发的交换机运行。
发布者将事件发给服务,IceStorm按照顺序将事件传递给订阅者。
使用这种方法,一个事件发布者就可以把一个事件发布给多个订阅者。
事件按照主题分类,订阅者可以指定他们感兴趣的主题。
只有订阅者感兴趣的主题才会发送给订阅者。
服务允许指定服务的质量,从而允许应用在可伸缩性和性能之间进行适当的折中。
如果你需要将信息发布到大量的应用组建,那么IceStorm是一个不错的选择。
(一个很典型的例子就是股票报价的应用)。
IceStorm减除了信息的发布者和订阅者之间的耦合,同时也能重新发布已经发布的信息。
另外,IceStorm可以作为联合服务运行,即多个服务的实例可以运行在不同的机器上,从而降低了CPU的负载。
4、IcePatch
IcePatch是一个软件补丁服务。
它允许你轻松的把软件的更新发布给客户。
客户连接到IcePatch然后请求更新一个特定的应用。
服务就自动检查客户软件的版本然后下载需要更新的组件。
而这些下载的组件都是放在一个压缩包里的,从而减少了带宽的占用。
软件补丁也可以通过结合Glacier服务发布,这样可以让只有经过授权的客户才能下载软件更新。
5、Glacier
Glacier是Ice防火墙服务:
它允许客户和服务器通过防火墙安全的通讯。
客户-服务器的通讯通过使用公钥认证完全加密,并且通讯是双向的。
Glacier提供了相互认证和安全的会话管理支持。
在客户端中如何定位服务器(即如何寻找代理)
直接看文档的最后几页。
以下是中文文档中关于端点的描述:
D.2端点
纲要
endpoint:
endpoint
描述
端点列表由一个或多个用冒号(:
)分隔的端点组成。
端点的格式如下所示:
protocoloption。
所支持的协议有tcp、udp、ssl,以及default。
如果使用了default,它会被Ice.Default.Protocol属性的值替代。
如果端点的格式有问题,或者指定了未知的协议,应用会收到Ice:
:
EndpointParseException。
只有安装了IceSSL插件,才能使用ssl协议。
各个协议及其所支持的选项将在下面描述。
TCP端点
纲要
tcp-hhost-pport-ttimeout-z
描述
tcp端点支持以下选项:
选项描述客户语义服务器语义
-hhost指定端点的主机名或IP地址。
如果没有指定,将使用Ice.Default.Host的值。
确定要连接到的主机名或IP地址。
确定对象适配器用于侦听连接的网络接口,以及在适配器所创建的代理中向外公布的主机名。
-pport指定端点的端口号。
确定要连接到的端口(必须指定)。
如果没有指定这个选项,或是port为零,端口将由操作系统选择。
以上是基于TCP协议的,关于UDP,SSL协议的也差不多
以下为聊天程序中连接LAN中一台服务器的代码:
#include
#include
usingnamespacestd;
usingnamespaceDemo;
intmain(intargc,char*argv[])
{
intstatus=0;
charstrtemp[100];//聊天内容
charclientname[20];//客户名
charchattmp[130];
Ice:
:
CommunicatorPtric;
try{
ic=Ice:
:
initialize(argc,argv);
/*连接服务器:
SimplePrinter16所申请的代理ID,default即为使用默认的协议TCP,-h192.168.1.16为服务端所在LAN中的IP地址,-p9600为端口号*/
Ice:
:
ObjectPrxbase=ic->stringToProxy("SimplePrinter16:
default-h192.168.1.16-p9600");
//创建一个Printer的代理(Printer即为客户端与服务器端的接口),利用checkedCast(base)检查代理是否存在
PrinterPrxprinter=PrinterPrx:
:
checkedCast(base);
if(!
printer){
throw"Invalidproxy";//代理不存在
}
else{
printf("请输入您的ID:
");
cin>>clientname;
}
while
(1){
cin>>strtemp;//输入聊天内容
if(strcmp(strtemp,"q")==0){
break;
}
//strcat(chattmp,clientname);
strcpy(chattmp,clientname);
strcat(chattmp,"say:
");
strcat(chattmp,strtemp);
printer->printString(chattmp);
}
//发给服务器的退出消息
printer->printString(clientname);
printer->printString("已退出!
");
cout<<"成功退出!
"<}catch(constIce:
:
Exception&ex){
cerr<status=1;
}catch(constchar*msg){
cerr<status=1;
}
if(ic){
try{
ic->destroy();
}catch(constIce:
:
Exception&ex){
cerr<status=1;
}
}
returnstatus;
}
ICE架构
1)slice
首先就是ice的对象模型,slice(specificationLanguageforIce)就是用来描述ice的对象模型的,有哪些接口,有哪些操作,以及要交换的数据类型。
可以把slice看成是一个合约,各种平台,各种语言映射,相互调用的公共接口,共同遵守的规则。
2)语言映射
目前ice提供了c++,java,c#,vb,python,php的语言映射。
因为各种语言的对象模型是不一样的,必须把这些不同的对象模型映射到同一个模型上,进行操作。
这就是一个抽象的过程。
直接去定义接口,然后剩下的工作就交给iceruntime来完成各种语言之间对象的相互转换。
3)客户机与服务器的结构
客户与服务器都由这样一些代码混合而成:
应用代码、库代码、根据Slice定义生成的代码
整个结构有两个方面:
客户端/服务器,它们共同使用的就是ice核心(iceruntime)
上图中最关键的部分就是ice核心,也就是iceruntime
Ice核心为远地通信提供了客户端和服务器端运行时支持。
其中的大量代码所涉及的是网络通信、线程、字节序,以及其他许多与网络有关的问题。
之所以被称为中间件,就是因为有了iceruntime把开发人员从繁琐的网络编程中解放出来了,让他们直接面对应用,解决业务逻辑这一块。
客户端=ice核心+代理代码+iceapi
服务器=ice核心+骨架(skeleton)代码+对象适配器+iceapi
proxy和skeleton都是由slice的定义生成的。
对象适配器会把来自客户的请求映射到编程语言对象上的特定方法。
4)ice协议
ice协议主要有两部分:
一个是编码规则,另一个是状态机。
双向连接的特性使得ice能穿越防火墙,NAT边界,还支持压缩,在低带宽链接上很有用。
5)对象持久
Ice拥有内建的对象持久服务,叫作Freeze。
你用Slice定义你的对象要存储的状态,Freeze编译器会生成代码,用以在数据库中存储和取回对象状态。
缺省使用的berkeleydb作为数据库。
利用ICE编写程序的几个注意点
利用ICE写程序时,一定要注意的几件事
1、用Windows作为服务器是一件非常不爽的事。
2、在windows下写客户端的时候,一定要用slice2xxx.exe的版本,否则在vc中可能编译过去,会有一些奇怪的问题,可能是vc中的stl与stl_port还会有一定的本质区别。
3、涉及到汉字的时候,一定要记得将utf8码转换成gbk码,要不一定是乱码
附转码程序:
//stdafx.h:
includefileforstandardsystemincludefiles,
// orprojectspecificincludefilesthatareusedfrequently,but
// arechangedinfrequently
//
#if!
defined(AFX_STDAFX_H__2843B98C_6C05_4A40_9CBC_51BD61B69760__INCLUDED_)
#defineAFX_STDAFX_H__2843B98C_6C05_4A40_9CBC_51BD61B69760__INCLUDED_
#if_MSC_VER>1000
#pragmaonce
#endif//_MSC_VER>1000
#defineVC_EXTRALEAN //Excluderarely-usedstufffromWindowsheaders
#undef_WINDOWS_
#include //MFCcoreandstandardcomponents
#include //MFCextensions
#include //MFCsupportforInternetExplorer4CommonControls
#ifndef_AFX_NO_AFXCMN_SUPPORT
#include //MFCsupportforWindowsCommonControls
#endif//_AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
//MicrosoftVisualC++willinsertadditionald