RO15 – 深入RemObjects SDK消息流内幕-客户端
本文深入探讨
RemObjects SDK
客户端调用流程内幕
,
向服务端发送调用
,
返回服务端的响应
.
上图展示了客户端向服务端的一个调用
:
用户代码调用本地代理的一个方法
–
如
- Sum(1,2) .
代理对象负责将调用通过网络传递给服务器
,Invoker
接收它并调用服务去执行
Sum()
方法
.
返回过程与此相同
,
代理向用户代码返回执行结果
.
上图的流程如果你只想使用
RO SDK
开发程序已经足够了
,
但是如果你想使用
RO
扩展你自己的组件或想了解
RO
的深层次技术
,
我们需要再向深层次挖掘
.
我们将上图再增加一些细节
,
更加详细的了解内幕
在这个图中
,
我们可以看到一下新的对象帮助消息传递和执行
,
返回执行结果
.
看看其中的细节
:
消息(Message)
可能你很熟悉消息类
,
在创建服务端和客户端的时候都会拖放消息控件
.
但是消息是做什么的呢
?
消息对象用来分割方法调用信息的
,
将服务名
,
调用的方法名
,
需要传递的参数封装起来
.
不同的消息使用不同的方式完成这个任务
,RO
提供了两种消息类型
: BinMessage
和
SOAPMessage.
第一个问题
,
如何将这些信息写入消息对象的
?
如果查看
RO
为你调用的每个服务自动生成的代理代码
(**_Intf.pas file),
你将发现如下内容
:
function TNewService_Proxy.Sum(const A: Integer;const B: Integer): Integer;
var __request, __response : TMemoryStream;begin
__request := TMemoryStream.Create;__response := TMemoryStream.Create;
try
__Message.Initialize(__TransportChannel, 'NewLibrary',__InterfaceName, 'Sum');__Message.Write('A', TypeInfo(Integer), A, []);__Message.Write('B', TypeInfo(Integer), B, []);__Message.Finalize;
...
由于代码生成单元的每个函数的参数都是已知的
,
所有可以创建
Delphi
代码将参数写入到消息中
.
首选消息使用库名称
,
接口服务名称和要调用的方法名称初始化
.
接下来
,
使用
Write()
方法加入每个参数
,
最后完成完成
.
现在消息对象将信息写入流中发送到网络
.
使用不同的消息格式会有微小的差距 .
使用不同的消息格式会有微小的差距 .
...
__Message.WriteToStream(__request);
__TransportChannel.Dispatch(__request, __response);
__Message.ReadFromStream(__response);
...
在代理的代码中我们看到消息内容写入流
,
通过传输通道传输
.
最终我们得到响应
,
处理会继续进行
,
但我们不在深入
.
传输通道
像消息类
,
你可能也很属性传输通道了
,
因为
RO
会在组件面板上安装各种类型的通道控件
.
多数通道都与服务端做一对一的映射
,
但是有些更通用可以和不同的服务端连接
(
如
HTTP
或
TCP).
传输通道的工作和简单
:
调用
Dispatch()
将信息流传递给
IntDispatch,
这是一个在
TROTransportChannel
中定义的虚拟方法
,
在子类中根据具体情况重写
(Override).
根据通道类型的不同
,
方法可能会建立与服务器的网络连接发送
Email
或使用本地通讯如
Window
消息机制或命名管道连接到服务器
.
管道与服务端对话后
,
就会向服务端传递请求流并最终返回服务端响应信息
.