Ice 是 Internet Communications Engine 的简称,出自ZeroC名门之下。
Ice 是一种面向对象的中间件平台。从根本上说,这意味着Ice 为构建面向对象的客户-服务器应用提供了工具、API 和库支持。Ice 应用适合于异构平台环境中使用:客户和服务器可以采用不同的编程语言,可以运行在不同的操作系统和机器架构上,并且可以使用多种网络技术进行通信。无论部署环境如何,这些应用的源码都是可移植的。
Ice 是一种面向对象的中间件平台。从根本上说,这意味着Ice 为构建面向对象的客户-服务器应用提供了工具、API 和库支持。Ice 应用适合于异构平台环境中使用:客户和服务器可以采用不同的编程语言,可以运行在不同的操作系统和机器架构上,并且可以使用多种网络技术进行通信。无论部署环境如何,这些应用的源码都是可移植的。
其采用C/S 模式结构,支持同步调用方式和异步调用方式,异步派发调用方式。支持跨语言的对象调用。多种语言之间采用共同的Slice(Specification Language for Ice)进行沟通。支持ice到C,JAVA,C#,VB,Python,Ruby,PHP等多种语言的映射。
工欲善其事,必先利其器,我们首先从www.zero.com,下载最新安装包;
btw:
目前最新的v3.3
http://www.zeroc.com/download_beta.html
最新稳定版本:
http://www.zeroc.com/download.html
由于我自己的平台是CentOS release 4.4 (Final),java version "1.6.0_01"
所以下载的是:
http://www.zeroc.com/download/Ice/3.3/Ice-3.3b-rhel4-i386-rpm.tar.gz
解开之后:
-rw-r--r-- 1 506 users 1130231 4月 1 10:39 db46-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 51459 4月 1 10:39 db46-devel-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 810562 4月 1 10:40 db46-java-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 72125 4月 1 10:40 db46-utils-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 84281 4月 1 10:15 ice-3.3b-1.rhel4.noarch.rpm
-rw-r--r-- 1 506 users 450359 4月 1 10:15 ice-c++-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 2823701 4月 1 10:16 ice-java-3.3b-1.rhel4.noarch.rpm
-rw-r--r-- 1 506 users 263085 4月 1 10:16 ice-java-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 3439061 4月 1 10:17 ice-libs-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 162092 4月 1 10:19 ice-php-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 739055 4月 1 10:19 ice-python-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 32913 4月 1 10:19 ice-python-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 223577 4月 1 10:19 ice-ruby-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 21406 4月 1 10:19 ice-ruby-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 3657167 4月 1 10:20 ice-servers-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 4350193 4月 1 10:24 ice-utils-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 74856 4月 1 10:40 mcpp-devel-2.6.4-1ice.rhel4.i386.rpm
由于需要c和java的包:
所以我们仅安装:
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-utils-3.3b-1.rhel4.i386.rpm
rpm -ivh mcpp-devel-2.6.4-1ice.rhel4.i386.rpm
rpm -ivh ice-servers-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-c++-devel-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-java-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-java-devel-3.3b-1.rhel4.i386.rpm
安装之后的Ice相关路径:
slice2cpp,slice2java在/usr/bin/下
Ice.jar 存储于 /usr/share/java/下
相关的Ice的库存储于/usr/lib下.
一切就绪,我们开始Ice之旅的Slice地带:
首先,我们建立一个demo.ice的文件:
注意,后两个"}"一定要包含";",否则slice2java就会过不去,赫赫
执行:
slice2java demo.ice
会在当前目录产生一个Demo目录,目录下自动生成:
-rw-r--r-- 1 root root 2316 4月 15 17:01 _testDelD.java
-rw-r--r-- 1 root root 560 4月 15 17:01 _testDel.java
-rw-r--r-- 1 root root 1929 4月 15 17:01 _testDelM.java
-rw-r--r-- 1 root root 4177 4月 15 17:01 _testDisp.java
-rw-r--r-- 1 root root 1070 4月 15 17:01 testHolder.java
-rw-r--r-- 1 root root 488 4月 15 17:01 test.java
-rw-r--r-- 1 root root 481 4月 15 17:01 _testOperations.java
-rw-r--r-- 1 root root 460 4月 15 17:01 _testOperationsNC.java
-rw-r--r-- 1 root root 5418 4月 15 17:01 testPrxHelper.java
-rw-r--r-- 1 root root 569 4月 15 17:01 testPrxHolder.java
-rw-r--r-- 1 root root 567 4月 15 17:01 testPrx.java
到目前为止,demo.ice所以Ice接口部分的定义以及相关依赖都已经自动生成.
我们要实现自己的execute方法,覆盖testPrx.java的同名方法:
看到了,就是这么简单,仅仅覆盖_testDisp里面的抽象方法,实现把我们自己的实现代码填充到里面就行了.
之后,我们建立一个Server服务在10000端口进行侦听。
貌似很复杂,其实里面的很多内容都是固定格式,有些部分需要固定和约定。其中上述红色部分是修改部分。
到目前为止,我们已经完成了大部分工作,我们还需要建一个客户端来对服务端的方法进行调用。
也貌似很复杂吧,其实不然,也很简单,同样包含很多固定格式。其中
是我们自己调用的逻辑。
赫赫,大功告成了,现在我们开始运行Server,再运行Client看到了么?
"My first Ice demo"
得到这样的结果,基本Ice之旅的Java部分简单实例我们基本完成。
Ice的性能和稳定性远超于我们的想象,skype知道么?其部分通讯架构就是采用的Ice.
btw:
目前最新的v3.3
http://www.zeroc.com/download_beta.html
最新稳定版本:
http://www.zeroc.com/download.html
由于我自己的平台是CentOS release 4.4 (Final),java version "1.6.0_01"
所以下载的是:
http://www.zeroc.com/download/Ice/3.3/Ice-3.3b-rhel4-i386-rpm.tar.gz
解开之后:
-rw-r--r-- 1 506 users 1130231 4月 1 10:39 db46-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 51459 4月 1 10:39 db46-devel-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 810562 4月 1 10:40 db46-java-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 72125 4月 1 10:40 db46-utils-4.6.21-2ice.rhel4.i386.rpm
-rw-r--r-- 1 506 users 84281 4月 1 10:15 ice-3.3b-1.rhel4.noarch.rpm
-rw-r--r-- 1 506 users 450359 4月 1 10:15 ice-c++-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 2823701 4月 1 10:16 ice-java-3.3b-1.rhel4.noarch.rpm
-rw-r--r-- 1 506 users 263085 4月 1 10:16 ice-java-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 3439061 4月 1 10:17 ice-libs-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 162092 4月 1 10:19 ice-php-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 739055 4月 1 10:19 ice-python-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 32913 4月 1 10:19 ice-python-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 223577 4月 1 10:19 ice-ruby-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 21406 4月 1 10:19 ice-ruby-devel-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 3657167 4月 1 10:20 ice-servers-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 4350193 4月 1 10:24 ice-utils-3.3b-1.rhel4.i386.rpm
-rw-r--r-- 1 506 users 74856 4月 1 10:40 mcpp-devel-2.6.4-1ice.rhel4.i386.rpm
由于需要c和java的包:
所以我们仅安装:
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm
rmp -ivh ice-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-utils-3.3b-1.rhel4.i386.rpm
rpm -ivh mcpp-devel-2.6.4-1ice.rhel4.i386.rpm
rpm -ivh ice-servers-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-libs-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-c++-devel-3.3b-1.rhel4.i386.rpm
rpm -ivh ice-java-3.3b-1.rhel4.noarch.rpm
rpm -ivh ice-java-devel-3.3b-1.rhel4.i386.rpm
安装之后的Ice相关路径:
slice2cpp,slice2java在/usr/bin/下
Ice.jar 存储于 /usr/share/java/下
相关的Ice的库存储于/usr/lib下.
一切就绪,我们开始Ice之旅的Slice地带:
首先,我们建立一个demo.ice的文件:
注意,后两个"}"一定要包含";",否则slice2java就会过不去,赫赫
执行:
slice2java demo.ice
会在当前目录产生一个Demo目录,目录下自动生成:
-rw-r--r-- 1 root root 2316 4月 15 17:01 _testDelD.java
-rw-r--r-- 1 root root 560 4月 15 17:01 _testDel.java
-rw-r--r-- 1 root root 1929 4月 15 17:01 _testDelM.java
-rw-r--r-- 1 root root 4177 4月 15 17:01 _testDisp.java
-rw-r--r-- 1 root root 1070 4月 15 17:01 testHolder.java
-rw-r--r-- 1 root root 488 4月 15 17:01 test.java
-rw-r--r-- 1 root root 481 4月 15 17:01 _testOperations.java
-rw-r--r-- 1 root root 460 4月 15 17:01 _testOperationsNC.java
-rw-r--r-- 1 root root 5418 4月 15 17:01 testPrxHelper.java
-rw-r--r-- 1 root root 569 4月 15 17:01 testPrxHolder.java
-rw-r--r-- 1 root root 567 4月 15 17:01 testPrx.java
到目前为止,demo.ice所以Ice接口部分的定义以及相关依赖都已经自动生成.
我们要实现自己的execute方法,覆盖testPrx.java的同名方法:
- //TestImp.java
- package Demo;
- import Ice.Current;
- public class TestImp extends _testDisp{
- public String execute(String mth, String cmd, Current __current) {
- // TODO Auto-generated method stub
- return mth+cmd;
- }
- }
之后,我们建立一个Server服务在10000端口进行侦听。
- //Server.java
- package Demo;
- public class Server {
- public static void main(String[] args) {
- int status = 0;
- Ice.Communicator ic = null;
- try {
- ic = Ice.Util.initialize(args);
- Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints(
- "TestAdapter", "default -p 10000");
- Ice.Object object = new TestImp();
- adapter.add(object, ic.stringToIdentity("TestAdapter"));
- 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);
- }
- }
貌似很复杂,其实里面的很多内容都是固定格式,有些部分需要固定和约定。其中上述红色部分是修改部分。
到目前为止,我们已经完成了大部分工作,我们还需要建一个客户端来对服务端的方法进行调用。
- package Demo;
- public class Client {
- public static void main(String[] args) {
- int status = 0;
- Ice.Communicator ic = null;
- try {
- ic = Ice.Util.initialize(args);
- // Ice.ObjectPrx base = ic
- // .stringToProxy("SimplePrinter:tcp -h 172.17.12.101 -p 10000");
- Ice.ObjectPrx base = ic
- .stringToProxy("TestAdapter:default -p 10000");
- testPrx test = testPrxHelper.checkedCast(base);
- if (test == null)
- throw new Error("Invalid proxy");
- System.out.println(test.execute("My first Ice ", "demo"));
- //System.out.println("ok");
- } 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);
- }
- }
也貌似很复杂吧,其实不然,也很简单,同样包含很多固定格式。其中
是我们自己调用的逻辑。
赫赫,大功告成了,现在我们开始运行Server,再运行Client看到了么?
"My first Ice demo"
得到这样的结果,基本Ice之旅的Java部分简单实例我们基本完成。
Ice的性能和稳定性远超于我们的想象,skype知道么?其部分通讯架构就是采用的Ice.
ZeroC ICE之旅------Slice
Slice是在ICE所特有的特殊语言,ICE 提供基于Ice语言的多语言映射工具。Slice主要针对程序所涉及到的接口和类型进行定义。不涉及到具体实现和具体语言的特征。
既然ICE支持跨语言的调用,那么是不是Slice支持每种的特有数据类型呢?
当然不是,ICE只是保留各种具体语言数据类型的最小交集。
提供:
string 采用Unicode编码,具有很好的国际化语言支持。
下面主要在介绍一下Slice的特性和约束:
1. Slice文件必须以.ice结尾,其他结尾方案的文件会被编译器拒绝。
2. Slice 文件格式实际就是text文本描述,由于Slice形式自由,可以用任何文本编辑器进行编辑。
3. Slice 支持#ifndef,#define,#endif,#include
例如:
在include 要避免使用双引号"",以及"",而要使用"/"
例如:
#include "Clock.ice" // 不推荐采用;
#include <SliceDefs/Clock.ice> // 正确
#include <SliceDefs\Clock.ice> // 非法
4.Slice 中文件的结构,模块,接口,类型出现的顺序,,可以按照你的喜好而自由定义。
5.Slice 的词法规则很多来源于C++和Java,只有少量的差异。
6.可以采用c++的注释规则。// 或
7.Slice 的关键词需要区分大小写:
关键词:
8.在接口定义的时候也避免使用非Slice关键字,但是C++ 或 Java关键字的标识符。
例如:switch
9.Ice保留了所有以"ice"作为开始标识符。保留以"Helper","Holder","Prx","Ptr"结尾的标识符。所以大家定义的时候最好避免一些不必要的麻烦。
10.Ice可以通过module嵌套的方式,类似于c++的namespace和java的包的概念。
11.除了刚才提到的Slice支持的基础类型外,还支持用户自定义类型:enumerations, structures, sequences, and dictionaries.
enumerations:枚举就不要介绍了,采用C++的语法形式
enum Fruit { Apple, Pear, Orange };
Structures:结构,也是采用C++的语法形式,避免,结构中定义结构
sequence:序列号类型,映射到java采用的数组方式实现,而不是所谓的集合容器类型对象存储。映射到C++中则采用STL容器存储。
sequence<int> values;
dictionary:字典类型,映射到java采用Map 进行存储,映射到C++采用map进行存储.
dictionary<int,string> myValues;
12.常量定义可以直接使用,但常量的定义必须是基本类型或枚举类型.定义形式也是采用C++定义方式.
13.方法的定义,形式类型java的方法定义,方法返回可以使void或对象类型.
14.Slice支持方法异常的定义,以及异常的继承.关于异常机制,我想java开发者可能更加熟悉,
例如:
Ice的错误机制也是异常强大,吸取了很多Java关于异常机制的特点.
Slice还包括很多良好的特性,在这里就不一一列举,对于支持自定义类型,基本类型,异常支持,对于一般的网络通讯应用已经足够了,更多Slice语言的介绍参阅其帮助.
Ice为我们提供了强大而又丰富的Slice,可以利用Slice,结合我们应用的特点,定义间接的Slice描述。
btw:
虽然Slice提供给我们丰富的功能和特性,在此我还是建议大家尽量采用基本类型和非异常机制.这样会对系统性能会带有一定的帮助。
另外接口的定义我想大家能够保持KISS(Keep it It Simple)设计原则,会使我们的应用看起来更美丽。
不要过度的使用Slice,否则会给我们带来无尽的烦恼。
既然ICE支持跨语言的调用,那么是不是Slice支持每种的特有数据类型呢?
当然不是,ICE只是保留各种具体语言数据类型的最小交集。
提供:
- 1.bool (false or true,>=1bit)
- 2.byte (-128-127@,>=8bits)
- 3.short (-2^15 to 2^15-1,>=16bits)
- 4.int (-2^31 to 2^31-1,>=32bits)
- 5.long (-2^63 to 2^63-1,>=64bits)
- 6.float (IEEE single-precision,>=32bits)
- 7.double (IEEE double-precision,>=64bits)
- 8.string (All Unicode characters, excluding ,the character with all bits zero.)
string 采用Unicode编码,具有很好的国际化语言支持。
下面主要在介绍一下Slice的特性和约束:
1. Slice文件必须以.ice结尾,其他结尾方案的文件会被编译器拒绝。
2. Slice 文件格式实际就是text文本描述,由于Slice形式自由,可以用任何文本编辑器进行编辑。
3. Slice 支持#ifndef,#define,#endif,#include
例如:
- // File Clock.ice
- #ifndef _CLOCK_ICE
- #define _CLOCK_ICE
- // #include directives here...
- // Definitions here...
- #endif _CLOCK_ICE
在include 要避免使用双引号"",以及"",而要使用"/"
例如:
#include "Clock.ice" // 不推荐采用;
#include <SliceDefs/Clock.ice> // 正确
#include <SliceDefs\Clock.ice> // 非法
4.Slice 中文件的结构,模块,接口,类型出现的顺序,,可以按照你的喜好而自由定义。
5.Slice 的词法规则很多来源于C++和Java,只有少量的差异。
6.可以采用c++的注释规则。// 或
7.Slice 的关键词需要区分大小写:
关键词:
- bool enum implements module struct
- byte exception int Object throws
- class extends interface out true
- const false local sequence void
- dictionary float LocalObject short
- double idempotent long string
例如:switch
9.Ice保留了所有以"ice"作为开始标识符。保留以"Helper","Holder","Prx","Ptr"结尾的标识符。所以大家定义的时候最好避免一些不必要的麻烦。
10.Ice可以通过module嵌套的方式,类似于c++的namespace和java的包的概念。
11.除了刚才提到的Slice支持的基础类型外,还支持用户自定义类型:enumerations, structures, sequences, and dictionaries.
enumerations:枚举就不要介绍了,采用C++的语法形式
enum Fruit { Apple, Pear, Orange };
Structures:结构,也是采用C++的语法形式,避免,结构中定义结构
- 合法:
- struct TimeOfDay {
- short hour; // 0 - 23
- short minute; // 0 - 59
- short second; // 0 - 59
- };
- 无效:
- struct TwoPoints {
- struct Point { // Illegal!
- short x;
- short y;
- };
- Point coord1;
- Point coord2;
- };
sequence:序列号类型,映射到java采用的数组方式实现,而不是所谓的集合容器类型对象存储。映射到C++中则采用STL容器存储。
sequence<int> values;
dictionary:字典类型,映射到java采用Map 进行存储,映射到C++采用map进行存储.
dictionary<int,string> myValues;
12.常量定义可以直接使用,但常量的定义必须是基本类型或枚举类型.定义形式也是采用C++定义方式.
13.方法的定义,形式类型java的方法定义,方法返回可以使void或对象类型.
14.Slice支持方法异常的定义,以及异常的继承.关于异常机制,我想java开发者可能更加熟悉,
例如:
- exception Error {}; // Empty exceptions are legal
- exception RangeError {
- TimeOfDay errorTime;
- TimeOfDay minTime;
- TimeOfDay maxTime;
- };
- interface Clock {
- idempotent TimeOfDay getTime();
- idempotent void setTime(TimeOfDay time)
- throws RangeError, Error;
- };
Ice的错误机制也是异常强大,吸取了很多Java关于异常机制的特点.
Slice还包括很多良好的特性,在这里就不一一列举,对于支持自定义类型,基本类型,异常支持,对于一般的网络通讯应用已经足够了,更多Slice语言的介绍参阅其帮助.
Ice为我们提供了强大而又丰富的Slice,可以利用Slice,结合我们应用的特点,定义间接的Slice描述。
btw:
虽然Slice提供给我们丰富的功能和特性,在此我还是建议大家尽量采用基本类型和非异常机制.这样会对系统性能会带有一定的帮助。
另外接口的定义我想大家能够保持KISS(Keep it It Simple)设计原则,会使我们的应用看起来更美丽。
不要过度的使用Slice,否则会给我们带来无尽的烦恼。
ZeroC ICE之旅------多语言互通互联
ce的服务端可以采用C++/Java/Python/C#等实现,客户端可以采用C++/Java/Python/C#/VB/PHP/Ruby来实现,就是说我的一个服务端采用C++实现,客户端可以采用java/php/vb/c# 等其他语言实现。
这个特性也是Ice的很重要的优势之一.
Ice的多语言之间如何确保对象的正确传输,每种语言都有各自的特点,数据类型,Ice是如何达到各种语言之间的互通互联的呢?
那么就一定提到Slice语言.Slice是保证各种语言的互通互联的关键,它是独立于其它任何语言,Ice可以通过把Slice代码片断转化为各自的
语言描述.
赫赫够多!
Slice的全称:Specification Language for Ice,是Ice自己的特殊语言,一种用于使对象接口与其实现相分离的基础性抽象机制。Slice 建立在客户与服务器之间的合约,用以描述应用所使用的类型和对象接口。Slice描述独立于实现语言,所以客户实现语言是否与编写服务器所用的语言相同没有任何关系。
slice语言片段可以被编译为任何所支持语言的实现。目前Ice Slice可以支持映射到到C++, Java, C#, Python,Ruby, and PHP。
因为Slice主要对接口和类型的定义和描述,没有实现部分。
到底如何实现不同语言的互通互联的呢?我们已Java,C++作为Ice例子原形,实际上我们仅仅做少量修改,就可以实现
C++的服务端,Java的客户端。Server和Client还是保持在同一台机器上运行。注意我们基于同一个demo.ice的事例。
首先运行./Server,再运行Client,看到结果了么?赫赫,是不是出现了正常结果。
到目前没有我们所有实例都是基于同一台机器的,实际情况Server,Client会分布在不同机器上。这种情况下,我们需要如何处理呢?
这个很简单,在Server少量修改
"default -p 10000" 采用 "tcp -h server1 -p port" 替代
Server所在主机IP:172.17.12.101 ,端口:10000
所以就修改为:tcp -h 172.17.12.101 -p 10000,再重新编译Server
编译方式参见:
http://masterkey.iteye.com/blog/183307
下面我们需要对Client连接部分进行修改,同理:
看到了么,就是这么简单,其他部分不用修改。
好了,我们进行验证,首先启动./Server,再执行Client ,看到了
"My first Ice 事例" 看到了么,祝贺你,跨语言的分布式调用例子你已经实现了。
其实Ice的通讯机制极其强大,支持集群和容错技术。关于集群的事例会在日后的文章中介绍。
BTW:
注意,Server运行之后监听于10000端口,需要修改iptables,允许其他机器可以连接。
编辑 iptables
vi /etc/sysconfig/iptables
追加:
这个特性也是Ice的很重要的优势之一.
Ice的多语言之间如何确保对象的正确传输,每种语言都有各自的特点,数据类型,Ice是如何达到各种语言之间的互通互联的呢?
那么就一定提到Slice语言.Slice是保证各种语言的互通互联的关键,它是独立于其它任何语言,Ice可以通过把Slice代码片断转化为各自的
语言描述.
- -rwxr-xr-x 1 system users 447888 2007-03-09 slice2java
- -rwxr-xr-x 1 system users 67753 2007-03-09 slice2py
- -rwxr-xr-x 1 system users 38679 2007-03-09 slice2rb
- -rwxr-xr-x 1 system users 505441 2007-03-09 slice2vb
- -rwxr-xr-x 1 system users 507119 2007-03-09 slice2cpp
- -rwxr-xr-x 1 system users 454347 2007-03-09 slice2cs
赫赫够多!
Slice的全称:Specification Language for Ice,是Ice自己的特殊语言,一种用于使对象接口与其实现相分离的基础性抽象机制。Slice 建立在客户与服务器之间的合约,用以描述应用所使用的类型和对象接口。Slice描述独立于实现语言,所以客户实现语言是否与编写服务器所用的语言相同没有任何关系。
slice语言片段可以被编译为任何所支持语言的实现。目前Ice Slice可以支持映射到到C++, Java, C#, Python,Ruby, and PHP。
因为Slice主要对接口和类型的定义和描述,没有实现部分。
到底如何实现不同语言的互通互联的呢?我们已Java,C++作为Ice例子原形,实际上我们仅仅做少量修改,就可以实现
C++的服务端,Java的客户端。Server和Client还是保持在同一台机器上运行。注意我们基于同一个demo.ice的事例。
首先运行./Server,再运行Client,看到结果了么?赫赫,是不是出现了正常结果。
到目前没有我们所有实例都是基于同一台机器的,实际情况Server,Client会分布在不同机器上。这种情况下,我们需要如何处理呢?
这个很简单,在Server少量修改
- Ice::ObjectAdapterPtr adapter = ic->createObjectAdapterWithEndpoints ("TestAdapter", "default -p 10000");
"default -p 10000" 采用 "tcp -h server1 -p port" 替代
Server所在主机IP:172.17.12.101 ,端口:10000
所以就修改为:tcp -h 172.17.12.101 -p 10000,再重新编译Server
- #include <Ice/Ice.h>
- #include <demo.h>
- using namespace std;
- using namespace Demo;
- class Server:public test
- {
- public:
- ::std::string execute (const string & mth, const string & str,
- const Ice::Current &);
- public:
- Server ();
- };
- Server::Server ()
- {
- };
- std::string Server::execute (const string & mth, const string & str,
- const Ice::Current &)
- {
- cout << mth + str << endl;
- return mth + str;
- }
- int
- main (int argc, char *argv[])
- {
- int
- status = 0;
- Ice::CommunicatorPtr ic;
- try
- {
- ic = Ice::initialize (argc, argv);
- Ice::ObjectAdapterPtr adapter
- =
- ic->createObjectAdapterWithEndpoints ("TestAdapter",
- "tcp -h 172.17.12.101 -p 10000");
- Ice::ObjectPtr object = new Server;
- adapter->add (object, ic->stringToIdentity ("TestAdapter"));
- adapter->activate ();
- ic->waitForShutdown ();
- } catch (const Ice::Exception & e)
- {
- cerr << e << endl;
- status = 1;
- } catch (const char *msg)
- {
- cerr << msg << endl;
- status = 1;
- }
- if (ic)
- {
- try
- {
- ic->destroy ();
- }
- catch (const Ice::Exception & e)
- {
- cerr << e << endl;
- status = 1;
- }
- }
- return status;
- }
编译方式参见:
http://masterkey.iteye.com/blog/183307
下面我们需要对Client连接部分进行修改,同理:
- package Demo;
- public class Client {
- public static void main(String[] args) {
- int status = 0;
- Ice.Communicator ic = null;
- try {
- ic = Ice.Util.initialize(args);
- // Ice.ObjectPrx base = ic
- // .stringToProxy("SimplePrinter:tcp -h 172.17.12.101 -p 10000");
- Ice.ObjectPrx base = ic
- .stringToProxy("TestAdapter:tcp -h 172.17.12.101 -p 10000");
- testPrx test = testPrxHelper.checkedCast(base);
- if (test == null)
- throw new Error("Invalid proxy");
- System.out.println(test.execute("My first Ice ", "事例"));
- //System.out.println("ok");
- } 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);
- }
- }
看到了么,就是这么简单,其他部分不用修改。
好了,我们进行验证,首先启动./Server,再执行Client ,看到了
"My first Ice 事例" 看到了么,祝贺你,跨语言的分布式调用例子你已经实现了。
其实Ice的通讯机制极其强大,支持集群和容错技术。关于集群的事例会在日后的文章中介绍。
BTW:
注意,Server运行之后监听于10000端口,需要修改iptables,允许其他机器可以连接。
编辑 iptables
vi /etc/sysconfig/iptables
追加:
Zero ICE我们已经掌握其基本运行原理。下面我们主要介绍一下ICe的多端口邦定的问题。
ICE使用TCP/IP 和UDP协议,以及基于TCP/IP之上的SSL协议。SSL协议可以充分保障Server/Client数据传输的加密安全性问题。
在这里,Server如何在同一台主机监听多个端口。
关于TCP/IP还是UDP还是SSL协议的选择,还是要看具有应用的要求,通常情况下TCP/IP协议的ICE应用已经足够了。
在同一个主机主机上,ICE服务支持多端口的监听。
服务端注册: tcp -h host -p port1:tcp -h host -p port2形式,
例如:
IP:172.17.12.101,需要在10001和10000同时监听。
就可以写成:
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 10001
赫赫是不是很简单,运行之后,服务就监听于10000和10001端口,请注意:避免其他应用相冲突。
客户端连接可以采用如下3种形式:
1. tcp -h 172.17.12.101 -p 10000
2. tcp -h 172.17.12.101 -p 10001
3. tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 100001
是不是很爽。
无论Server监听在多个端口,还是只有唯一的一个Server在工作,
对于Client较多的应用或负载要求很高的情况下,我们可以把Server程序运行于多台主机之上。通过集群方式合理有效的化解来自Client的压力。
例如:
ServerA 172.17.12.101 tcp -h 172.17.12.101 -p 10000
ServerB 172.17.12.102 tcp -h 172.17.12.102 -p 10000
ServerC 172.17.12.103 tcp -h 172.17.12.103 -p 10000
Client可以如下的连接方式:
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000:tcp -h 172.17.12.103 -p 10000
或是
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000
等多种情况,可以根据应用的具体要求合理有效的构造所需连接主机的字符串。
这种连接方式是不是很cool。
其实这种连接方式可以有效地利用ICE提供的load balancing功能,把Client的每个请求合理的分配到每个Server。从而有效地避免了Client大量请求对同一台Server的巨大压力。
ICE的load balancing主要采用round-robin算法,round-robin是一种非常有效的负载均衡算法.
大家会问了,如果某个Server如果宕机,那么这个Client还能正常工作么?
这个问题问得好,其实ICE自身提供一种极其强大容错技术功能。
具体体现在如果当某个Server(假设是ServerA)宕机之后,来自Client的请求分配到ServerA服务器上,Client会自动记录ServerA失效状态,会把请求再分配给可正常工作的Server(ServerB,ServerC),对于用户的每次请求都能分配到正常的服务主机上(除非A,B,C都同时宕机).当ServerA回复正常之后,Client会自动感知ServerA工作状态.Client的请求又可以有效地分配到上述A,B,C主机上.这一切对于开发者都是透明的.
ICE所提供的集群功能和容错功能是极其强大的.
Client状态感知的变化和更新完全不需要Client重新启动。
ICE使用TCP/IP 和UDP协议,以及基于TCP/IP之上的SSL协议。SSL协议可以充分保障Server/Client数据传输的加密安全性问题。
在这里,Server如何在同一台主机监听多个端口。
关于TCP/IP还是UDP还是SSL协议的选择,还是要看具有应用的要求,通常情况下TCP/IP协议的ICE应用已经足够了。
在同一个主机主机上,ICE服务支持多端口的监听。
服务端注册: tcp -h host -p port1:tcp -h host -p port2形式,
例如:
IP:172.17.12.101,需要在10001和10000同时监听。
就可以写成:
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 10001
赫赫是不是很简单,运行之后,服务就监听于10000和10001端口,请注意:避免其他应用相冲突。
客户端连接可以采用如下3种形式:
1. tcp -h 172.17.12.101 -p 10000
2. tcp -h 172.17.12.101 -p 10001
3. tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.101 -p 100001
是不是很爽。
无论Server监听在多个端口,还是只有唯一的一个Server在工作,
对于Client较多的应用或负载要求很高的情况下,我们可以把Server程序运行于多台主机之上。通过集群方式合理有效的化解来自Client的压力。
例如:
ServerA 172.17.12.101 tcp -h 172.17.12.101 -p 10000
ServerB 172.17.12.102 tcp -h 172.17.12.102 -p 10000
ServerC 172.17.12.103 tcp -h 172.17.12.103 -p 10000
Client可以如下的连接方式:
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000:tcp -h 172.17.12.103 -p 10000
或是
tcp -h 172.17.12.101 -p 10000:tcp -h 172.17.12.102 -p 10000
等多种情况,可以根据应用的具体要求合理有效的构造所需连接主机的字符串。
这种连接方式是不是很cool。
其实这种连接方式可以有效地利用ICE提供的load balancing功能,把Client的每个请求合理的分配到每个Server。从而有效地避免了Client大量请求对同一台Server的巨大压力。
ICE的load balancing主要采用round-robin算法,round-robin是一种非常有效的负载均衡算法.
大家会问了,如果某个Server如果宕机,那么这个Client还能正常工作么?
这个问题问得好,其实ICE自身提供一种极其强大容错技术功能。
具体体现在如果当某个Server(假设是ServerA)宕机之后,来自Client的请求分配到ServerA服务器上,Client会自动记录ServerA失效状态,会把请求再分配给可正常工作的Server(ServerB,ServerC),对于用户的每次请求都能分配到正常的服务主机上(除非A,B,C都同时宕机).当ServerA回复正常之后,Client会自动感知ServerA工作状态.Client的请求又可以有效地分配到上述A,B,C主机上.这一切对于开发者都是透明的.
ICE所提供的集群功能和容错功能是极其强大的.
Client状态感知的变化和更新完全不需要Client重新启动。
来源:oschina
链接:https://my.oschina.net/u/2273085/blog/610468