RO11 -用RemObjects SDK创建异步调用客户端

 
RO11 - RemObjects SDK 创建异步调用客户端
RemObjects SDK ( 简称 RO) 提供了创建异步客户端的功能 . 这个文档快速的介绍一下什么是异步客户端 , 如何通过 RO 执行 .
为什么使用异步调用 ?
通常当你的 RO 客户端程序向服务器端请求调用时 , 客户端执行过程会等待请求调用返回 , 这时请求传递给服务器 , 在服务器上处理 , 调用结果从服务器上返回 . 对于服务类型和请求的方法 , 用可能要等上几秒或更长时间 . 也就是说当你在 LAN Internet 上调用服务时可能会让客户明确的感觉到延时 , 应用程序看上去像死掉了一样 . 而且当处理过程超过几秒时 , 只向用户显示一个漏斗光标是不够的 , 客户可能会希望在服务器执行的过程中继续做其它的操作 .
异步调用正是让你完整这个功能 - 当服务器端处理请求时你的应用程序还是可响应的 .
这是怎么完成的呢 ? 在创建异步客户端时 , 所有向服务器请求的调用都分为独立的两个方法 : 一个提供所有的输入参数 (var Const) 调用后立即返回 , 另一个返回所有的输出参数 (Var,out Result).
加入有一个在服务器端执行的接口 , 其中的 Calc 方法执行要花费很长时间 ( 30 分钟 ):
type
  IComplexCalculation = interface
    function Calc(const iValueA, iValueB:integer; var ioValueC:integer):string;
 end;
可见 Calc 函数有 3 个输入参数和 2 个输出 (ioValueC 和返回值 ). 当在客户端异步调用时 , 接口对客户端而言应如下所示 :
type
  IComplexCalculation_Async = interface(IROAsync)
    procedure Invoke_Calc(const iValueA, iValueB, ioValueC:integer);
    function Receive_Calc(out ioValueC:integer):string;
 end;
注意新的接口如何产生两个变体的 Calc 方法 . 首先 , Invoke_Calc 传入的都是输入参数 , 另外一个 Receive_Calc 只返回输出部分 .
在客户端编码时你也要向其它 RO 客户端一样生产服务对象的代理 . 用户调用 Invoke_Calc 触发服务器端的计算 . 不象原来的 Calc 方法 ,Invoke_Calc 方法马上返回 , 用户可以继续使用应用程序 . 当服务器端执行完调用返回计算结果时 , 你可以调用 Receive_Calc 方法获取返回值并将之反馈给用户 . 在等待调用结果时 , 你的应用程序定时查看 AnswerReceived 属性 ( IROAsync 接口中定义 ) 判断调用是否完成 , 并可能相应的更新状态栏或菜单栏工具栏 .
使用 SDK 写一个异步客户端
现在你已经明白在特定情况下使用异步客户端的好处了 , 下面让我们看看使用 RO 提供的功能轻松创建异步客户端 ..
首先 , 异步调用完全在客户端 , 这意味着你可以使用他们去调用任意几经存在的 RO 服务 , 而不用去改变从编译部署服务 .
第一部创建你要调用的服务的异步调用接口 .RO 提供了多种方法从 RODL 创建异步接口 . 最简单的方法是使用 IDE. IDE 主菜单调用 RemObjects SDK | Regenerate Async unit 将在服务项目中生产新的异步调用单元 .
另外可以使用 Service Builder 的菜单项 CodeGen/Delphi/Async Interface:
RO11 -用RemObjects SDK创建异步调用客户端_第1张图片
第三种方式是使用 RODL.exe 实用程序从 RODL 文件生成代码 , 你可以用这种方式对任意的 RODL 文件生成 *_Async.pas 文件 . 不用担心你只有服务的 WSDL 文件 , 如你希望异步调用存在的 Soap web service, 你只要简单的将 WSDl 文件导入的 ServiceBuilder 中并保持为 RODL 文件即可 .
使用命令行从 RODL 中生成异步接口单元 , 使用如下命令 :
RODL /rodl:<path-to/rodl> /language:pascal /type:async
之后你将在 RODL 文件同目录下找到生成的 _Async.pas 文件 . 将之添加到你的客户端项目中一切 OK.
在你的应用程序中有两个按钮 , 一个是 "Invoke Calculation" 另一个是 "Show Result". 将第二个按钮的 Enabled 属性设置为 False.
在第一个按钮的事件处理中创建代理对象 ( 与其它 RO 客户端一样的方式 ), 将之保存为全局变量 ( 窗体成员 ) 并调用其函数 :
procedure btn_InvokeClick(...)
begin
 fProxy := CoCalcServer_Async.Create(BinMessage1, HttpChannel1);
 fProxy.Invoke_Calc(...);
 btn_Invoke.Enabled := false;
end ;
第二个按钮事件处理函数中简单的调用 Receive_Calc 函数并向用户展示返回的结果 :
procedure btn_ReceiveClick(...)
begin
 ShowMessage(Receive_Calc(...));
 fProxy := nil;
 btn_Invoke.Enabled := true;
 btn_Receive.Enabled := false;
end ;
最后增加一个 Timer 控件定时检查调用是否返回并将第二个按钮 Enabeld 属性设为 True. 设置 TTimer Interval 1000 并完成其事件处理函数 :
procedure timer_CheckTimer(...)
begin
 btn_Receive.Enabled := Assigned(fProxy) and fProxy.AnswerReceived;
end ;
现在启动你的程序只有 Invoke 按钮可用 , 一旦你点击它 , 它将不可用 , 应用程序将等待服务器的返回结果 . 注意现在你的用户接口是可以响应的 , 用户可以继续操作 . 当请求结果返回时 Show Result 按钮可用 , 用户点击查看结果 .
后台
异步调用在后台是如何执行的呢 .
首先 , 异步调用完全在客户端 . 这意味着在客户端 , 异步调用被发送到服务器端 , 并等待服务器端相应 .
为了不阻塞线程 (VCLGUI 线程或其它线程 ), 异步代理创建一个后台工作线程处理与服务器的通信 . 代理序列化原始消息 ( 调用方法的基本信息和所有输入参数 ) 后传递给后台线程 , 接下来马上返回 .
这个后台线程建立一个与服务器的连接 , 发送调用消息并等待响应 . 一旦它收到响应消息 , 马上传递给代理对象 , 后台线程结束 .
客户端应用程序调用 Receive_Calc 方法得到返回值 ( 或其它信息 ).
 

你可能感兴趣的:(timer,服务器,service,Integer,interface,pascal)