1、 参考《Ice 分布式程序设计》 马维达 译,冯立彬的博客 一、 Ice文件定义 Printer.ice文件内容如下: module demo { interface Printer { void printString(string s); }; }; 在命令行终端,进入到Printer.ice文件所在的目录,使用如下命令编译ice文件:slice2java printer.ice。会在目录下面生成一个demo文件夹,里面生成了一些java文件,如下图示: 二、 类图结构 这些文件的类图结构如下: ------------
2、
三、 文件说明
这里对生成的一些文件做些解释,分为两部份,服务端类文件及客户端类文件:
1. 服务器文件
l
3、 这是两个定义操作的接口文件,每个接口文件中定义了一个操作实现,定义的操作与Slice接口中定义的操作相一致,_PrinterOperationsNC中操作:void printString(String s),只是在_
4、以访问如下对象: 1、adapter 通过adapter 成员,你可以访问负责分派当前请求的对象适配器。通过适配器,你又可以访问它的通信器(通过getCommunicator 操作)。 2、id id 成员提供当前请求的对象标识。如: Ice.Current c Ice.Identity idCopy = new Ice.Identity();//new一个对象标示符idCopy对象 idCopy.name = c.id.name;//通过Current获取当前请求的servant对象标示符的name idCopy.category = c.id.categor
5、y;//对象标示符的category 每个Ice 对象都有一个唯一的对象标识。对象标识是用于把一个对象与其他所有对象区别开来的标识值。Ice 对象模型假定对象标识是全局唯一的,也就是说,在一个Ice 通信域中,不会有两个对象具有相同的对象标识。对象标示Identity只有两个成员,name和category成员。 3、facet 通过facet 成员,你可以访问请求的facet 。 4、operation operation 成员含有正在被调用的操作的名字。注意,这个操作名可 能是Ice::Object上的操作的名字,比如ice_ping 或ic
6、e_isA。如: public class PrinterI extends _PrinterDisp { public void printString(String s, Ice.Current current) { System.out.println(current.operation); } }//输出结果:printString 5、mode mode 成员含有操作的调用模式(Normal、Idempotent,或Nonmutating)。 6、ctx ctx 成员含有这个调用的当前上下文,上下文就是一系列名- 值对,如果客户在上下文中
7、放入一些名- 值对,并在发出调用时使用这个上下文,服务器就将能使用客户所发送的这些名- 值对。
在服务器端,操作的实现可以通过Ice.Current 的ctx 成员访问接收到的Context ,并提取客户所发送的名- 值对。
l _
8、通过引用传递。此类可以存放服务器返回给客户端的信息。
客户端使用out 参数传递holder 类的实例,并在调用完成时检查每个out 参数的value 成员。下面的Slice定义,所有的参数都是作为out 参数传递的:
struct NumberAndString {
int x;
string str;
};
sequence
9、t float f, out bool b, out string s); void op2(out NumberAndString ns,out StringSeq ss,out StringTable st); void op3(out ServerToClient* proxy); }; Slice 编译器为这个定义生成了以下out参数代码: public interface ClientToServerPrx extends Ice.ObjectPrx { public void op1(Ice.IntHolder i, Ice.FloatHo
10、lder f, Ice.BooleanHolder b,Ice.StringHolder s); public void op2(NumberAndStringHolder ns, StringSeqHolder ss,StringTableHolder st); public void op3(ClientToServerPrxHolder proxy); } 假定我们有一个代理,指向的是ServerToClient 接口,客户代码可以 这样传递参数: ClientToServerPrx p = ...; // Get proxy... Ice.IntH
11、older ih = new Ice.IntHolder(); Ice.FloatHolder fh = new Ice.FloatHolder(); Ice.BooleanHolder bh = new Ice.BooleanHolder(); Ice.StringHolder sh = new Ice.StringHolder(); p.op1(ih, fh, bh, sh); NumberAndStringHolder nsh = new NumberAndString(); StringSeqHolder ssh = new StringSeqHolder(); Stri
12、ngTableHolder sth = new StringTableHolder();
p.op2(nsh, ssh, sth);
ServerToClientPrxHolder stcph
= new ServerToClientPrxHolder();
p.op3(stcph);
System.out.writeln(ih.value);
一旦操作调用完成,值就会出现在各个holder 实例中,你可以通过每个实例的value 成员访问这些值。
2. 客户端文件
l
13、如PrinterPrx,在客户的地址空间中, PrinterPrx 的实例是“远地的服务器中的Printer接口的实例”的“本地大使”。与服务器端对象有关的所有细节,比如其地址、所用协议、对象标识,都封装在该实例中。
这个类的方法调用都是远程服务端的调用,执行printString()方法的具体实现是在远程服务端执行的。
l
14、端要得到服务端的servant的代理类,客户端不能通过new
15、va 的向下转换)。
与此相反, uncheckedCast 不会联系服务器,而是会无条件地返回具有所请求的类型的代理 。但是,如果你要使用uncheckedCast,你必须确定这个代理真的支持你想要转换到的类型;而如果你弄错了,你很可能会在调用代理上的操作时,引发运行时异常。对于这样的类型失配,最后可能会引发OperationNotExistException,但也有可能引发其他异常,比如整编异常。而且,如果对象碰巧有一个同名的操作,但参数类型不同,则有可能根本不产生异常,你最后就会把调用发送给类型错误的对象;这个对象可能会做出非常糟糕的事情。
l _
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818