1 ICE简介
1.1 简介
ICE(Internet Communications Engine)是一个中间件平台。作为一个高性能的互联网通信平台,ICE包含了很多分层的服务和插件(Plug-ins),并且简单、高效和强大。
ICE当前支持C++、Java、C#、Visual Basic、Python和PHP
编程语言,并支持在多种操作系统上运行。更多的操作系统和编程语言将会在以后的发布中支持。
1.2 组成部分
ICE有以下几部分组成:
1.2.1 Slice
Slice(Specification Language for Ice) ,ICE的规范语言,跟CORBA的IDL(Interface Definition Language)等价的东西,一种用于使对象
接口与其实现相分离的基础性抽象机制。Slice建立了客户端和服务器端共同遵守的契约:接口。Slice也用来描述对象持久数据。
Slice描述独立于实现语言,所以客户实现语言是否与编写服务器所用的语言相同没有任何关系。slice语言片段可以被编译为任何所支持语言的实现。目前Ice Slice可以支持映射到到C++, Java, C#, Python,Ruby, and PHP。因为Slice主要对接口和类型的定义和描述,没有实现部分。
1.2.2 Slice Compilers
Slice的规范语言可以影射成多种编程语言。目前ICE支持C++,Java,Python,PHP,C#和VB的语言影射。Ice的客户端和服务器端协同工作,而不会知道分别实现的是何种编程语言。
1.2.3 Ice
Ice的核心库。在众多的特性当中,Ice核心库通过一个高效的
协议(包含TCP/UDP层上协议压缩)来管理所有的通信任务,为多
线程服务器提供了一个灵活的线程池,并且有特别的功能来支持上百万对象的可
扩展性。
1.2.4 IceUtil
一些常用的功能函数集。例如Unicode处理和多线程编程,是用C++写成。
1.2.5 IceBox
一个专用于ICE应用的
应用服务器。ICEBox可以方便地运行和管理动态加载、共享库或java类的形式Ice的服务。
1.2.6 IcePack
一个成熟的服务激活和部署工具。IcePack能大大简化在异构网络之间部署应用的复杂性。只要简单的编写
XML格式的一个部署描述文件,IcePack就能自动处理剩下的工作。
1.2.7 Freeze
Freeze提供了Ice Servants对象的自动持久性。通过几行代码,一个应用就可以生成一个高度可扩展的逐出器(evictor)来高效地管理持久对象。
1.2.8 FreezeScript
在大的软件项目里,持久对象的数据类型改变很常见。为了最小化这些变化的影响,FreezeScript提供了相应的工具来检查和移植Freeze生成的数据库。这些工具支持XML格式的配置
脚本,易于使用。
1.2.9 IceSSL
用于Ice核心的动态的SSL传输插件。提供了认证、加密和消息完整性,使用工业标准的SSL协议来实现。
1.2.10 Glacier
面向对象中间件平台的一个最大的挑战是
安全性和防火墙。Glacier是Ice的防火墙解决方案,它大大简化了安全程序的部署。
Glacier认证和过滤客户的请求并允许服务器通过安全的方式回调客户端对象。
结合IceSSL的使用,Glacier提供了强大的安全解决方案,即安全,又易于配置管理。
1.2.11 IceStorm
一个支持联盟的消息服务。和大多数的其他消息和事件服务相比,IceStorm支持有类型的事件,这意味着通过联盟广播一个消息和调用一个接口上的一个方法一样容易。
1.2.12 IcePatch
一个软件修补和分发的服务。为确保运行的软件是最新的
版本,要经常更新软件,这是一件乏味的工作。IcePatch自动更新在某个目录层次下的文件。只有需要更新的文件会下作到客户端,为了快速的下载更新,IcePatch使用的高效的压缩
算法。
2 多语言分布式互联
Ice的
服务端可以采用C++/Java/Python/C#等实现,客户端可以采用C++/Java/Python/C#/VB/PHP/Ruby来实现。这个特性是Ice的很重要的优势之一。
2.1 概述
2.1.1 相同的开发环境
2.1.2 不同开发环境
2.2 接口
建立一个Printer.ice文件
module Demo {
interface Printer {
void printString(string s);
};
};
2.3 Java /Java
服务端采用java实现,客户端可以采用java实现。
2.3.1 实现接口
在
dos环境下执行 slice2java Printer.ice 命令
会在当前目录产生一个Demo目录,目录里自动生成如下文件:
_PrinterDel.java
_PrinterDelD.java
_PrinterDelM.java
_PrinterDisp.java
_Printer
Operations.java
_PrinterOperationsNC.java
Printer.java
PrinterHolder.java
PrinterPrx.java
PrinterPrxHelper.java
PrinterPrxHolder.java
PrinterI.java
package slice2java;
import Ice.Current;
import Demo._PrinterDisp;
/**
* _PrinterDisp 基类由slice2java编译器生成,它是一个抽象类。
* _PrinterDisp 抽象类包含一个printString()方法。
*/
public class PrinterI extends _PrinterDisp{
public void printString(String s, Current current)
{
System.out.println(s + " ice !");
}
}
2.3.2 Server端
Server.java
package server;
import slice2java.PrinterI;
import Ice.Util;
import Ice.ObjectAdapter;
import Ice.Object;
import Ice.Communicator;
public class Server {
public static void main(String[] args) {
int status = 0;
// 创建一个通信器的对象ic
Communicator ic = null;
try {
// 初始化Ice运行时
ic = Util.initialize();
/*
* 创建一个对象适配器(ObjectAdapter)对象adapter,并初始化之。
* 参数"SimplePrinterAdapter":表示适配器的名字。
* 参数"default -p 10000":表示适配器使用缺省协议(TCP/IP)在端口10000处
监听到来的请求。
*/
ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints(
"SimplePrinterAdapter", "default -p 10000");
Object object = new PrinterI();
// 将object添加到适配器,并命名为"SimplePrinter"
adapter.add(object, ic.stringToIdentity("SimplePrinter"));
// 激活适配器,以使服务器开始处理来自客户的请求
adapter.activate();
/*
* 挂起发出调用的线程,直到服务器实现终止为止.
* 或者是通过发出一个调用关闭运行时(run time)的指令来使服务器终止.
*/
ic.waitForShutdown();
} catch (Ice.LocalException e) {
e.printStackTrace();
status = 1;
} catch (Exception e) {
System.out.println(e.getMessage());
status = 1;
}
if (ic != null) {
// Clean up
//
try {
// 销毁通信连接
ic.destroy();
} catch (Exception e) {
System.out.println(e.getMessage());
status = 1;
}
}
System.exit(status);
}
}
2.3.3 Client端
Client.java
package client;
import Ice.Util ;
import Demo.PrinterPrxHelper ;
import Ice.ObjectPrx ;
import Demo.PrinterPrx ;
import Ice.Communicator ;
public class Client {
public static void main(String[] args) {
int status = 0;
Communicator ic = null;
try {
ic = Util.initialize();
/*
* 获取
远程对象的代理
* 创建一个代理对象,并用通信器的stringToProxy()方法初始化之.
*/
ObjectPrx base = ic
.stringToProxy("SimplePrinter:default -p 10000");
PrinterPrx printer = PrinterPrxHelper.checkedCast(base);
if (printer == null)
throw new Error("Invalid ice");
printer.printString("Hello ");
} catch (Ice.LocalException e) {
e.printStackTrace();
status = 1;
} catch (Exception e) {
System.out.println(e.getMessage());
status = 1;
}
if (ic != null) {
// Clean up
//
try {
ic.destroy();
} catch (Exception e) {
System.out.println(e.getMessage());
status = 1;
}
}
System.exit(status);
}
}
2.4 C++/ C++
服务端采用C++实现,客户端可以采用C++实现。
2.4.1 实现接口
在dos环境下执行 slice2cpp Printer.ice 命令
会在当前目录下产生两个文件,自动生成的文件如下:
Printer.h
Printer.cpp
2.4.2 Server端
2.4.3 Client端
2.5 C++/Java
服务端采用C++实现,客户端可以采用java实现。
我们已Java,C++作为Ice
例子原形,我们只需要运行C++服务端程序,在运行Java客户端程序就可以实现Java和C++互联互通。
目前没有我们所有实例都是基于同一台机器的,实际情况服务端和客户端会分布在不同机器上。这种情况下,我们需要如下修改:
"default -p 10000" 采用 "tcp -h server1 -p port" 替代
服务端所在主机IP: 10.0.68.18 ,端口:10080
所以就修改为:tcp -h 10.0.68.18 -p 10080,再重新编译就可以了
客户端也同样修改就可以了
如果要监听多个端口,我么可以如下修改:
服务端: tcp -h host -p port1:tcp -h host -p port2形式
例:
服务端 :
tcp -h 10.0.68.18 -p 10080: tcp -h 10.0.68.18 -p 10081
客户端:可以监听两个,也可以监听一个