RemObjects 客户端完整执行流程

RemObjects是一个强大的N层网络框架,写一个实现即可通过多种连接方式(http,tcp/ip,webservice...)被不同客户端调用
这里我将通过源代码展示一下客户端的调用过程,因为RO封装得实在太好,程序员根本不需要关心太多细节,只需要根据需求编写实现即可,了解其实现原理,可增强自己的设计思想,现在请一步一步来看下这个过程

首先是客户端调用就是这么简单,一个TRORemoteService对象转成服务端的一个接口,即可调用服务端的接口函数,
其实在程序启动的时候就已经完成了大多数工作了,先是看下主窗体的文件引用
 
当在界面摆上以下3个控件


 ROMessage: TROBinMessage; 
 RORemoteService: TRORemoteService;
 ROChannel: TROIndyTCPChannel;
会自动引入上图的文件, 这里的核心文件是 uROClient
先看下其初始化代码
 
该代码主要是创建了针对 消息类,通
道类,代理类 的管理列表对象

_MessageClasses := TClassList.Create; 消息类列表

_ProxyClasses := TStringList.Create; 代理类列表

_TransportChannels := TStringList.Create; 通道类列表


当我们使用一种消息格式的类时, 这里以BIN格式为例,引用的uROBinMessage文件会在程序启动之初,
将该对象处理类TROBinMessage加入消息类的列表
 
通道类也一样,这里以TROIndyTCPChannel 为例

客户端要调用服务端的接口INewService,需要服务端提供一个接口代理类TNewService_Proxy,
初始化时也是通过注册函数添加到uROClient里的代理类对象,
方式和 消息类,通道类 的过程类似 
 

以上部分就是程序一启动时所做的初始化工作

=============================

回到客户端的代码,一句代码是如何实现整个调用过程的呢?

首先RORemoteService是一个接口实现类对象,调用 as 操作时会使用接口查询,看下代码
 
这里会调用 FindProxyClass 函数到_ProxyClasses 代理类列表对象里搜索我们要调用的服务端接口 INewService 的代理类,
如果找到则返回该代理类对象,因为程序启动时 TNewService_Proxy 已经注册到 _ProxyClassess 里,所以这里实际返回的就是
TNewService_Proxy,返回后再创建实例对象proxy := proxyclass.Create(Self); 
 构造函数的参数是 TRORemoteService 对象自身;(RORemoteService as INewService) 返回的就是代理类的对象,
那么在创建代理类对象又做了些什么呢?
 TNewService_Proxy 类没有构造函数,所以这里调用的是其父类TROProxy 的构造函数


因为 RORemoteService 的对象的 Channel,Message属性分别为 ROChannel,ROMessage;
所以代理类对象其实就是把这两个对象给保存起来

返回来代理类对象,接下来是调用接口函数 Sum

代理类的__GetMessage属性获取的就是构造函数里传入的TRORemoteService对象的 Message 属性
 
同理获取通道对象,所以这里的 lMessage 实际上就是窗体的  ROMessage: TROBinMessage; 对象
lTransportChannel 实际上就是窗体的 ROChannel: TROIndyTCPChannel; 对象

接下来的代码开始对入参进行指定消息格式的打包

lMessage.InitializeRequestMessage(lTransportChannel, ‘NewLibrary‘, __InterfaceName, ‘Sum‘);

lMessage.Write(‘A‘, System.TypeInfo(Integer), A, []);

lMessage.Write(‘B‘, System.TypeInfo(Integer), B, []);

lMessage.Finalize;
首先是在请求数据头里写入要调用服务端接口及函数名称,然后再以序列化的方式写入入参数据




这里用到的对象序列化思想,简单地说就是把一个对象按一定的格式保存到流对象里,这个过程可以理解为 封包
数据按消息类打包后,调用通道类进行传输
lTransportChannel.Dispatch(lMessage);

这里的核心函数 IntDispatch 处理了 
连接:IndyClient.Connect;
发送:IndyClient.IOHandler.Write(lStream, lStream.Size, TRUE);
接收:IndyClient.IOHandler.ReadStream(lStream);
断开:IndyClient.Disconnect;
这里的 IndyClient 是 TIdTCPClient 类对象,
也就是 通道类TROIndyTCPChannel 底层通讯其实就是通过TIdTCPClient 实现的

 
 
服务端接收到数据后会 解包,然后调用数据头里的接口函数,计算返回的数据再 打包  发送到客户端,
客户端接收到返回的数据后,再 解包,并读取返回结果
lMessage.Read(‘Result‘, System.TypeInfo(Integer), Result, []);

以上这就是整个客户端的调用过程

时间: 2024-10-08 08:06:52

RemObjects 客户端完整执行流程的相关文章

hbase之createTable完整的netty实现执行流程

hbase的客户端代码并不想hive一样用java编写,shell调用,而是使用ruby编写. 在admin.rb文件中方法create,其中接受两个参数,其中第二个参数类型为变长参数. 而在create方法的最后,调用了admin.createTable,其中的admin是hbaes.rb初始化时通过调用java代码ConnectionFactory.createConnection创建的connection调用getAdmin而获得的. 下面简单分析一下ConnectionFactory.c

SpringMVC执行流程

下图展示了SpringMVC请求响应的完整流程: 用户想服务器发出请求,请求被Spring的前端控制器DispatcherServlet截获. DispatcherServlet对请求的URL(统一资源定位符)进行解析,得到URI(资源的标识符),根据URI调用HandlerMapping获得该Handler配置的所有相关对象,包括handler对象以及handler对象对应的拦截器,这些对象会被封装在一个HandlerExecutionChain对象当中返回. DispatcherServle

推荐:想了解一个项目完整测试流程,看这篇文章就OK了

推荐:想了解一个项目完整测试流程,看这篇文章就OK了 写在前面:本文来自真实企业测试人员的工作总结,用一个项目的进行流程为线索,记录每个阶段测试包含的内容及关注点. <ignore_js_op> 项目的测试流程大只包含的几个阶段:立项.需求评审.用例评审.测试执行.测试报告文档 一.立项后测试需要拿到的文档 1.需求说明书 2.原型图(及UI图) 3.接口文档 4.数据库字典(表的数量.缓存机制) 二.需求评审 参加人员:开发.测试及需求人员,由需求人员主持讲解. 为了会议的有效举行,测试及开

步步深入:MySQL架构总览-&gt;查询执行流程-&gt;SQL解析顺序

前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来探讨一下其中的知识. 一.MySQL架构总览: 架构最好看图,再配上必要的说明文字. 下图根据参考书籍中一图为原本,再在其上添加上了自己的理解. 从上图中我们可以看到,整个架构分为两层,上层是MySQLD的被称为的‘SQL Layer’,下层是各种各样对上提供接口的存储引擎,被称为‘Storage Engin

docker exec的具体执行流程

首先,做一个docker exec的请求: docker exec -it 5504f937f7bb sh 对应的docker -d(启动的docker daemon)的输出为: INFO[0211] POST /v1.20/containers/5504f937f7bb/exec      INFO[0211] POST /v1.20/exec/fc9c11ae6ac4827ea507e885c888bdb37c8f7b906347b9272adf8d580a6417df/start  INF

MySQL架构总览-&gt;查询执行流程-&gt;SQL解析顺序

前言: 一直是想知道一条SQL语句是怎么被执行的,它执行的顺序是怎样的,然后查看总结各方资料,就有了下面这一篇博文了. 本文将从MySQL总体架构--->查询执行流程--->语句执行顺序来探讨一下其中的知识. 一.MySQL架构总览: 架构最好看图,再配上必要的说明文字. 下图根据参考书籍中一图为原本,再在其上添加上了自己的理解. 从上图中我们可以看到,整个架构分为两层,上层是MySQLD的被称为的'SQL Layer',下层是各种各样对上提供接口的存储引擎,被称为'Storage Engin

Servlet执行流程和生命周期【慕课网搬】

Servlet执行流程(GET方式为例) 首先用户客户端浏览器发出Get方式(点击超链接方式)向浏览器发出请求. 服务器接收到客户端点击超链接,接收到GET请求之后,服务器到WEB.xml中<servlet-mapping>标签中来寻找与之对应的URl地址,从而找到相对应的servlet名字,再根据该名字到标签中找与之相对应的处理类(继承至HttpServlet类),执行该类中的doget()[超链接方式,服务器可以自行分析]方法. Servlet的生命周期 调用构造方法创造servlet实例

ServletContext--HttpServletResponse--web项目执行流程

一.ServletContext 接口(javax.servlet) 定义:public interface ServletContext 原理:     Tomcat启动的时候,需要识别webapps下的各个WEB应用,识别各个WEB应用的同时为每个WEB应用创建对应的对象ServletContext,一个WEB应用对应一个ServletContext.ServletContext内置了2种至少MAP结构的数据,一种用于存放整个web应用中配置的键值对的参数信息,另外一种用于存放程序运行过程中

走进Struts2(一) — Struts2的执行流程及其工作原理

 Struts2是一套很优秀的Web应用框架,实现优雅.功能强大.使用简洁.能够说是Struts2是一款很成熟的MVC架构. 在我们学习Struts2时,最好是先学习它的执行流程.核心概念.从中得到启示.提升自己,而不不过学习怎么怎么使用它. 在网上看到这样一句话: 你千万不要成为一个仅仅会熟练使用框架的程序猿.那样.你会疲于奔命,你或许永远仅仅会使用 Hadoop ,而写不出一个 Hadoop ,你仅仅是一个 Hadoop程序猿,而不是一个分布式project师. 你或许永远仅仅会使用 Str