微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

RO代码跟踪 之 客户端代理类的工作原理

  每个服务都会自动在XXX_Intf.pas文件生成一个代理类TXXXService_Proxy,这个代理类从TROProxy类继承并实现了IXXXService接口.
  我们在客户端调用RO服务的时候,是这样做的:
var
  fFirstService: IFirstSampleService;  //定义接口变量
begin
  fFirstService := (RORemoteService as IFirstSampleService);  //获取接口
  NamesBox.Items.CommaText := fFirstService.Nicknames(eFullname.Text);  //调用
end;

  对程序下断点后会发现客户端调用服务端方法的时候都是通过代理类中对应的方法转发给服务端.
function TFirstSampleService_Proxy.Nicknames(const FullName: Widestring): Widestring;
begin
  try
    //将参数和函数名称写入到消息中
    __Message.InitializeRequestMessage(__TransportChannel,'FirstSample',__InterfaceName,'Nicknames');
    __Message.Write('FullName',TypeInfo(Widestring),FullName,[]);
    __Message.Finalize;
    //写完后使用通道传输
    __TransportChannel.dispatch(__Message);
    //读取返回的结果
    __Message.Read('Result',result,[]);
  finally
    __Message.UnsetAttributes(__TransportChannel);
    __Message.FreeStream;
  end
end;
  首先解释一下调用是如何跳转到代理类的.[这种方式很常见哦,看看THTTPRIO控件吧,delphi调用WebService的时候貌似也是用这种技巧]
  在执行fFirstService := (RORemoteService as IFirstSampleService);代码时,调用RORemoteService控件中的一个成员函数:
function TRORemoteService.QueryInterface(const IID: TGUID; out Obj): HResult; override;
var //ref : IInterface;
    proxyclass : TROProxyClass;
    proxy : TROProxy;
begin
  result := inherited QueryInterface(IID,Obj);

  if (result <> S_OK) then begin
    proxyclass := FindProxyClass(IID,TRUE);

    if (proxyclass=NIL) then Exit    else begin     CheckCanConnect(false);      proxy := proxyclass.Create(fMessage,fChannel);      proxy.GetInterface(IID,Obj);//关键之处 使Obj :=proxy      result := S_OK;    end;  end;end;    在跟踪一下FindProxyClass方法,就会发现原来在XXX_Inft.pas单元中的initialization节中将代理类注册全局变量_ProxyClasses中,在做类型转换的时候由QueryInterface函数来查找注册的代理类,并创建代理类实例返回.所以fFirstService := (RORemoteService as IFirstSampleService);最终获取到的是代理类的实例.在QueryInterface方法中会将RORemoteService的Message和Channel属性类传递个代理类实例.我们在代理类中看到的__Message成员实际上就是我们指定的RO Message控件,而__TransportChannel则是我们指定的通道.  注意:QueryInteface是IUnKNown接口定义的方法,类在实现接口的时候必须要实现的三个方法之一.[用于获取实现接口的对象]  代理类做的事情就很直接了,首先将需要传给服务端的信息如函数名称,参数全部流化到__Message中,使用通道传输这个流,并接收服务端返回的结果. 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐