第六章编写客户端程序_第1页
第六章编写客户端程序_第2页
第六章编写客户端程序_第3页
第六章编写客户端程序_第4页
第六章编写客户端程序_第5页
已阅读5页,还剩49页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、山东大学计算机科学与技术学院基础技术教学部第六章第六章 编写客户端程序编写客户端程序山东大学计算机科学与技术学院第六章第六章 编写客户端程序编写客户端程序基本知识基本知识diidsi接口库接口库上下文上下文山东大学计算机科学与技术学院基础技术教学部基本知识基本知识山东大学计算机科学与技术学院请求请求请求:是一个请求:是一个corba伪对象,与一个请求对象相关伪对象,与一个请求对象相关联的信息包括目标对象引用,操作名字,联的信息包括目标对象引用,操作名字,0或多个参或多个参数,可选的上下文,以及用于存放返回结果或异常数,可选的上下文,以及用于存放返回结果或异常信息的环境信息的环境封装一个请求有两

2、种格式封装一个请求有两种格式 静态:请求对象由静态:请求对象由idl桩隐式发送桩隐式发送 动态:显式创建一个请求对象,选择一种通信方式发送并获取动态:显式创建一个请求对象,选择一种通信方式发送并获取响应结果,由接口响应结果,由接口request描述描述山东大学计算机科学与技术学院request接口接口定义了对一个定义了对一个corba对象的某一操作的一次调用请对象的某一操作的一次调用请求求调用一个操作之前必须首先获取目标对象引用调用一个操作之前必须首先获取目标对象引用见见p140山东大学计算机科学与技术学院调用类型调用类型静态调用:客户程序在编译前就知道静态调用:客户程序在编译前就知道idl接

3、口信息接口信息动态调用:动态调用: 编写客户程序时尚未确定编写客户程序时尚未确定idl接口类型接口类型 运行时利用接口库服务提供的信息创建一个请求对象运行时利用接口库服务提供的信息创建一个请求对象 大部分任务是建立请求对象,而不是调用过程本身大部分任务是建立请求对象,而不是调用过程本身山东大学计算机科学与技术学院选择调用类型选择调用类型简单性简单性 dii需由程序员手工完成需由程序员手工完成idl桩所完成的任务桩所完成的任务灵活性灵活性调用性能调用性能通信方式通信方式 sii支持同步,单向支持同步,单向 dii支持三种:同步,单向,延迟同步支持三种:同步,单向,延迟同步小结:能用小结:能用si

4、i则用则用sii山东大学计算机科学与技术学院编写客户程序编写客户程序静态静态public class client public static void main(string args) org.omg.corba.orb orb=org.omg.corba.orb.init(args, null); / 利用利用poa全称与对象标识全称与对象标识bankmanager查找帐户管理员查找帐户管理员 bank.accountmanager manager = bank.accountmanagerhelper.bind( orb, /bankpoa, bankmanager.getbytes(

5、); string name = args.length 0 ? args0 : david zeng; / 请求帐户管理员找出一个指定名字的帐户,无此帐户则新开一个请求帐户管理员找出一个指定名字的帐户,无此帐户则新开一个 bank.account account = manager.open(name); system.out.println(name + “的帐户余额为的帐户余额为” + account.getbalance() + 元元); account.deposit(200); system.out.println(“存款存款200元后,余额为元后,余额为” + account.g

6、etbalance() + “元元”); if (account.withdraw(600) system.out.println(“取款取款600元后,余额为元后,余额为” + account.getbalance() + 元元); else system.out.println(余额不足余额不足600元,取款失败,余额保持不变元,取款失败,余额保持不变); 客户程序client.java初始化初始化orb绑定到服务对象绑定到服务对象调用服务对象提供的服务调用服务对象提供的服务山东大学计算机科学与技术学院public class client() public static void mai

7、n(string args) org.omg.corba.orb orb = org.omg.corba.orb.init(args,null); org.omg.corba.object manager = (com.inprise.vbroker.orb.orb) orb).bind(“bankpoa”,”bankmanager”.getbytes(),null,null); org.omg.corba.request requestopen = manager._request(“open”); string name = args.length0?args0:”david”;. req

8、uestopen.add_in_arg().insert_string(name); requestopen.set_return_type(orb.get_primitive_tc(org.omg.corba.tckind.tk_objeref); requsetopen.invoke(); org.omg.corba.object account = requestopen.result().value().extract_object(); org.omg.corba.request requestbalance = account._request(“getbalance”); req

9、uestbalance.set_return_type(orb.get_primitive_tc(org.omg.corba.tckind.tk_float); requestbalance.invoke(); float bal=requestbalance.resutl().value().extract_float(); system.out.println(“帐户帐户”+name+”的余额为的余额为”+bal); 初始化org获取帐户管理员的通用对象引用创建一个调用manager的open()操作的请求对象设置请求的实际参数设置请求的返回结果的类型以同步通信方式发送请求提取返回结果继续

10、以dii方式调用account的getbalance()方法编写客户程序编写客户程序动态动态山东大学计算机科学与技术学院基础技术教学部2 动态调用机制动态调用机制山东大学计算机科学与技术学院动态调用机制动态调用机制基本接口基本接口动态调用过程动态调用过程编程编程山东大学计算机科学与技术学院基础技术教学部基本接口基本接口山东大学计算机科学与技术学院动态调用接口动态调用接口corba:object:定义每个:定义每个corba对象都必须支对象都必须支持的方法持的方法corba: orb:定义客户端和服务端都能使用的操:定义客户端和服务端都能使用的操作,是内核实现的方法作,是内核实现的方法corba

11、: request:定义远程对象操作:定义远程对象操作corba: list:用于构建参数列表,维护一个由构:用于构建参数列表,维护一个由构造类型造类型namevalue组成的数据项列表组成的数据项列表山东大学计算机科学与技术学院伪对象伪对象idl对象类由对象类由idl语言描述并需要向语言描述并需要向boa和和orb核核心登记和管理,而且心登记和管理,而且idl对对 象类都继承基类象类都继承基类corbaobject伪对象类尽管也可以由伪对象类尽管也可以由idl语言描述,但是,它不语言描述,但是,它不需要向需要向 boa和和orb核心登记,也不需要继承核心登记,也不需要继承corbaobjec

12、t类。类。伪对象类包括伪对象类包括environment、nameval ue、nvlist、request、serverrequest、context、princial、typecode、boa和和orb。 山东大学计算机科学与技术学院corba:orb见见p141create_list:生成一个空的:生成一个空的nvlist对象对象create_operation_list:生成:生成nvlist对象,利用客户对象,利用客户描述的操作参数自动进行填充,并将已赋值的描述的操作参数自动进行填充,并将已赋值的nvlist返回给客户返回给客户山东大学计算机科学与技术学院corba:object(对

13、象引用)(对象引用)创建一个请求,在目标对象上执行创建一个请求,在目标对象上执行 _request: 创建一个请求对象后,可调用该请求对象的创建一个请求对象后,可调用该请求对象的add_in_arg(),add_name_in_arg()等方法为调用操作设置一个或等方法为调用操作设置一个或多个实参多个实参 _create_request:调用前必须先创建操作的实参:调用前必须先创建操作的实参山东大学计算机科学与技术学院corba:request(操作请求)(操作请求)add_arg:在请求格式中添加参数:在请求格式中添加参数invoke:完成一个调用:完成一个调用/返回操作返回操作send:根

14、据请求中的信息发起操作,不需等待操作:根据请求中的信息发起操作,不需等待操作结果就将控制返回给调用者结果就将控制返回给调用者pull_reponse:检查请求操作是否完成:检查请求操作是否完成get_reponse:回送执行请求的结果信息:回送执行请求的结果信息山东大学计算机科学与技术学院nvlist(参数与返回值)(参数与返回值)用于构造参数列表的接口用于构造参数列表的接口add_item:把一个新的参数加到指定的列表中:把一个新的参数加到指定的列表中free_memory:山东大学计算机科学与技术学院基础技术教学部动态调用过程动态调用过程山东大学计算机科学与技术学院clienserver1

15、 get_interface2 lookup_name3describe4 create_list5 add_item (1-n)6 create_request7 invoke8 delete9 freeinterfacedefoperationdefcorba:orbcorba:nvlistcorba:objectorb:request动态调用环境接口库环境山东大学计算机科学与技术学院一:查询接口定义信息1 客户调用目标对象中的get_interface操作。调用后,客户得到一个存放在接口库中的interfacedef对象,从而获得目标对象的接口描述信息山东大学计算机科学与技术学院二:寻找

16、操作的描述2 以interacedef对象作为接口库导航的入口点,找出有关的接口对象以及它所支持的操作。(通过调用interfacedef的lookup_name操作,得到operationdef对象)3 调用operationdef对象中的describe(),获得需调用的操作的完整描述,即操作的全部idl定义山东大学计算机科学与技术学院三. 准备参数列表4 调用orb接口中用于动态调用的create_list方法,创建一个空闲的参数列表,即nvlist对象5 调用nvlist上的add_item(),将各个请求参数逐一填入参数列表中山东大学计算机科学与技术学院四。创建请求对象6 调用目标对

17、象上的,从corba:object接口继承的create_request操作,构造一个请求对象。在请求中指出操作名,参数和返回结果参数山东大学计算机科学与技术学院五。调用已建立的请求7 调用orb:request对象中的invoke操作,发起对请求的调用六 善后8 执行orb:request对象的delete操作,释放请求对象和相关的内存空间9 调用orb:nvlist对象上free操作,释放列表结构的相关空间山东大学计算机科学与技术学院public class client() public static void main(string args) org.omg.corba.orb or

18、b = org.omg.corba.orb.init(args,null); org.omg.corba.object manager = (com.inprise.vbroker.orb.orb) orb).bind(“bankpoa”,”bankmanager”.getbytes(),null,null); org.omg.corba.request requestopen = manager._request(“open”); string name = args.length0?args0:”david”;. requestopen.add_in_arg().insert_string

19、(name); requestopen.set_return_type(orb.get_primitive_tc(org.omg.corba.tckind.tk_objeref); requsetopen.invoke(); org.omg.corba.object account = requestopen.result().value().extract_object(); org.omg.corba.request requestbalance = account._request(“getbalance”); requestbalance.set_return_type(orb.get

20、_primitive_tc(org.omg.corba.tckind.tk_float); requestbalance.invoke(); float bal=requestbalance.resutl().value().extract_float(); system.out.println(“帐户帐户”+name+”的余额为的余额为”+bal); 初始化org获取帐户管理员的通用对象引用创建一个调用manager的open()操作的请求对象设置请求的实际参数设置请求的返回结果的类型以同步通信方式发送请求提取返回结果继续以dii方式调用account的getbalance()方法实例实例山

21、东大学计算机科学与技术学院基础技术教学部客户端客户端dii编程编程山东大学计算机科学与技术学院实现规范实现规范客户可以使用客户可以使用dii对任意多个接口的对象发起调用对任意多个接口的对象发起调用对一个接口的一部分对象发起调用,另一部分用静对一个接口的一部分对象发起调用,另一部分用静态存根调用态存根调用可对一个接口的一个对象有时使用可对一个接口的一个对象有时使用dii,有时使用静,有时使用静态存根态存根用一组用一组api获得和解析一个调用,实现并返回结果获得和解析一个调用,实现并返回结果山东大学计算机科学与技术学院编写编写dii获取目标对象引用获取目标对象引用创建请求对象创建请求对象传递实际参

22、数并指定返回类型传递实际参数并指定返回类型发送请求并等待响应发送请求并等待响应提取结果提取结果山东大学计算机科学与技术学院步骤步骤向目标对象询问描述目标对象接口信息的对象,并向目标对象询问描述目标对象接口信息的对象,并将其放在接口库中将其放在接口库中从接口库的对象中,找到所要调用的操作的描述从接口库的对象中,找到所要调用的操作的描述建立调用参数表,并逐一填入参数建立调用参数表,并逐一填入参数创建请求。请求中包含目标对象的引用,方法名,创建请求。请求中包含目标对象的引用,方法名,参数表和返回值参数表和返回值调用请求,并作善后处理调用请求,并作善后处理山东大学计算机科学与技术学院1 获取目标对象引

23、用获取目标对象引用因为编译客户程序时目标对象的接口类型通常尚未因为编译客户程序时目标对象的接口类型通常尚未确定,因而没有可用帮助类确定,因而没有可用帮助类扩展两个扩展两个bind()方法方法public org.omg.corba.object bind( string fullpoaname,/poa全名 byte objectid,/对象标识 string hostname,/对象所在主机名字 bindoptions options/绑定选项)public org.omg.corba.object bind( string repositoryid,/接口库标识 string object

24、name,/对象名 string hostname,/对象所在主机名字 bindoptions options/绑定选项)org.omg.corba.object manager = (com.inprise.vbroker.orb.orb) orb).bind(“bankpoa”,”bankmanager”.getbytes(),null,null);山东大学计算机科学与技术学院2 创建请求对象创建请求对象对目标对象引用的某一操作的一次调用对目标对象引用的某一操作的一次调用发起请求时,请求对象被打包通过发起请求时,请求对象被打包通过orb发送到服务端发送到服务端 使用使用sii时,该过程对程

25、序员是透明的时,该过程对程序员是透明的 使用使用dii,必须由程序员自己显式创建并发送请求对象,必须由程序员自己显式创建并发送请求对象必须由程序员自己显式地创建并发送请求对象,必须由程序员自己显式地创建并发送请求对象,_request()/_create_requestorg.omg.corba.request request = manager._request(“open”);山东大学计算机科学与技术学院3 传递实参并指定返回类型传递实参并指定返回类型请求对象中操作的实际参数表被表示为一个请求对象中操作的实际参数表被表示为一个nvlist实例,是若干实例,是若干namedvalue对象的列

26、表,每个对象的列表,每个namedvalue是一三元组是一三元组(名字,值,标志名字,值,标志)山东大学计算机科学与技术学院4 发送请求和提取结果发送请求和提取结果invoke():阻塞,处理完返回:阻塞,处理完返回send_deferred():非阻塞:非阻塞return_value()山东大学计算机科学与技术学院public class client() public static void main(string args) org.omg.corba.orb orb = org.omg.corba.orb.init(args,null); org.omg.corba.object ma

27、nager = (com.inprise.vbroker.orb.orb) orb).bind(“bankpoa”,”bankmanager”.getbytes(),null,null); org.omg.corba.request requestopen = manager._request(“open”); string name = args.length0?args0:”david”;. requestopen.add_in_arg().insert_string(name); requestopen.set_return_type(orb.get_primitive_tc(org.o

28、mg.corba.tckind.tk_objeref); requsetopen.invoke(); org.omg.corba.object account = requestopen.result().value().extract_object(); org.omg.corba.request requestbalance = account._request(“getbalance”); requestbalance.set_return_type(orb.get_primitive_tc(org.omg.corba.tckind.tk_float); requestbalance.i

29、nvoke(); float bal=requestbalance.resutl().value().extract_float(); system.out.println(“帐户帐户”+name+”的余额为的余额为”+bal); 初始化org获取帐户管理员的通用对象引用创建一个调用manager的open()操作的请求对象设置请求的实际参数设置请求的返回结果的类型以同步通信方式发送请求提取返回结果继续以dii方式调用account的getbalance()方法2.4 实例实例山东大学计算机科学与技术学院_accountstub.javadii public boolean withdraw

30、(float amount) org.omg.corba.request _request = this._request(withdraw); _request.set_return_type(_orb().get_primitive_tc(org.omg.corba.tckind.tk_boolean); org.omg.corba.any _param_amount = _request.add_in_arg(); _param_amount.insert_float(float)amount); _request.invoke(); java.lang.exception _excep

31、tion = _request.env().exception(); if (_exception != null) throw (org.omg.corba.systemexception) _exception; boolean _result; _result = _request.return_value().extract_boolean(); return _result; 山东大学计算机科学与技术学院_accountstub.javasii public boolean withdraw (float amount) while (true) if (!_is_local() o

32、rg.omg.corba.portable.outputstream _output = null; org.omg.corba.portable.inputstream _input = null; boolean _result; try _output = this._request(withdraw, true); _output.write_float(float)amount); _input = this._invoke(_output); _result = _input.read_boolean(); return _result; catch (org.omg.corba.

33、portable.applicationexception _exception) final org.omg.corba.portable.inputstream in = _exception.getinputstream(); java.lang.string _exception_id = _exception.getid(); throw new org.omg.corba.unknown(unexpected user exception: + _exception_id); catch (org.omg.corba.portable.remarshalexception _exc

34、eption) continue; finally this._releasereply(_input); else final org.omg.corba.portable.servantobject _so = _servant_preinvoke(withdraw, _opsclass); if (_so = null) continue; final bank.accountoperations _self = (bank.accountoperations)_so.servant; try return _self.withdraw(amount); 山东大学计算机科学与技术学院基础

35、技术教学部dsi山东大学计算机科学与技术学院动态框架动态框架dsi允许允许server在运行时刻动态对任意对象予以实现在运行时刻动态对任意对象予以实现 可以实现任意多个接口的对象可以实现任意多个接口的对象 可以实现一个接口中的一部分对象,另一部分由静态框架实现可以实现一个接口中的一部分对象,另一部分由静态框架实现 不必继承由不必继承由idl编译器生成的框架(编译器生成的框架(poa类),也不必使用纽类),也不必使用纽带机制间接使用带机制间接使用poa类类山东大学计算机科学与技术学院原理原理poaimplserverrequestserverrequestir山东大学计算机科学与技术学院开发步骤

36、开发步骤利用回调方法利用回调方法invoke()接收从接收从orb转发来的一个转发来的一个serverrequest类型的请求对象类型的请求对象从请求对象中提取实际参数向上调用真正执行服务从请求对象中提取实际参数向上调用真正执行服务的伺服对象的方法的伺服对象的方法将结果或异常填入请求对象中将结果或异常填入请求对象中山东大学计算机科学与技术学院1 对象对象serverrequestclass serverrequest public:const char * operation() const;void argument(nvlist_prt& parmaters);context_pt

37、r ctx();void set_result(const any& value);void set_exception(const any& value);;作用:实现动态框架功能山东大学计算机科学与技术学院arguments(inout nvlist nv): 得到输入型参数的值。得到输入型参数的值。 准备:按照对应操作的准备:按照对应操作的idl定义为定义为nvlist进行初始赋值,包括设置每进行初始赋值,包括设置每个元素的类型码和标志(个元素的类型码和标志(flags,输入输出类型),输入输出类型) 执行后,执行后,nvlist得到输入型参数值得到输入型参数值 完成功能

38、后,在完成功能后,在nvlist中设置返回的值中设置返回的值set_result():设置返回结果的值:设置返回结果的值set_exception(): 抛出异常抛出异常山东大学计算机科学与技术学院2 请求实现请求实现dsi方式下,对象的请求交给动态实现例程方式下,对象的请求交给动态实现例程dir(dynamic implementation routine)完成:接收请求,获得请求的操作信息,动态决定如何实现对完成:接收请求,获得请求的操作信息,动态决定如何实现对象,最后返回结果象,最后返回结果dir: 不是某一特定接口的实现对象不是某一特定接口的实现对象 通过对象适配器获得一个请求,并进一

39、步获得该请求的操作信息通过对象适配器获得一个请求,并进一步获得该请求的操作信息 动态决定如何实现该对象动态决定如何实现该对象 通过对象适配器返回输出结果通过对象适配器返回输出结果需要实现需要实现dir的例程要由特定对象实现(实现的例程要由特定对象实现(实现dynamicimplementation接口)接口)interface dynamicimplementationvoid invoke();山东大学计算机科学与技术学院import org.omg.corba.*;import org.omg.portableserver.*;public class bankimpl extends o

40、rg.omg.portableserver.dynamicimplementation / 属性的定义 protected java.util.map accountlist;/ 所有账户的列表 protected orb orb;/ 用于创建请求对象的orb伪对象 protected poa poa;/ 用于创建新对象引用的poapublic bankimpl(orb orb, poa poa) accountlist = new java.util.hashmap(); this.orb = orb; this.poa = poa; / orb回调方法,是每一个采用dsi的对象实现都必须实

41、现的方法需要实现该接口构造方法,管理员开始时管理的账户清单为空3 程序实例程序实例山东大学计算机科学与技术学院 public void invoke(serverrequest request) / 根据当前对象引用取对象标识(对account而言,对象标识就是账户名字) string objectid = new string(_object_id(); system.out.println(objectid + executing + request.operation() + () .); / 根据请求对象中的操作名字分别处理 if (request.operation().equals

42、(open) / 开设账户操作 try org.omg.corba.nvlist paramlist = orb.create_list(0); org.omg.corba.any param = orb.create_any(); param.insert_string(); paramlist.add_value(name, param, org.omg.corba.arg_in.value); request.arguments(paramlist); string name = paramlist.item(0).value().extract_string(); / 执行开户操作,在

43、账户清单中查找或开设指定名字的账户 if (accountlist.get(name) = null) java.util.random random = new java.util.random(); float balance = math.abs(random.nextint() % 100000 / 100f; accountlist.put(name, new float(balance); system.out.println(新开账户: + name); org.omg.corba.object account = poa.create_reference_with_id( na

44、me.getbytes(), idl:bank/account:1.0); org.omg.corba.any result = orb.create_any(); result.insert_object(account); request.set_result(result); catch(exception exc) exc.printstacktrace(); 从请求对象中获取实际参数往请求对象中填写返回结果创建一any型,并填入“ ”山东大学计算机科学与技术学院 else if (request.operation().equals(deposit) / 存款操作 try / 根据对

45、象标识取账户余额 float balance = (float) accountlist.get(objectid); if (balance = null) throw new org.omg.corba.bad_param(); / 从请求对象中获取参数 org.omg.corba.nvlist paramlist = orb.create_list(0); org.omg.corba.any param = orb.create_any(); param.insert_float(0); paramlist.add_value(amount, param, org.omg.corba.a

46、rg_in.value); request.arguments(paramlist); float amount = paramlist.item(0).value().extract_float(); / 执行存款操作 accountlist.remove(objectid); accountlist.put(objectid, new float(balance.floatvalue() + amount); / 该操作没有返回结果 catch(exception exc) exc.printstacktrace(); 山东大学计算机科学与技术学院 else if (request.ope

47、ration().equals(withdraw) / 取款操作 try / 根据对象标识取账户余额 float balance = (float) accountlist.get(objectid); if (balance = null) throw new org.omg.corba.bad_param(); / 从请求对象中获取参数 org.omg.corba.nvlist paramlist = orb.create_list(0); org.omg.corba.any param = orb.create_any(); param.insert_float(0); paramlist.add_value(amount, param, org.omg.corba.arg_in.value); request.arguments(paramlist); float amount = paramlist.item(0).value().extract_float(); / 执行取款操作并填写请求对象中的返回结果 org.omg.corba.any result = orb.create_any(); if (balance.floatvalue() amount) result.insert_boolean(false);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论