RemObjects是一個強大的N層網絡框架,寫一個實現即可通過多種連接方式(http,tcp/ip,webservice...)被不同客戶端調用
這里我將通過源代碼展示一下客戶端的調用過程,因為RO封裝得實在太好,程序員根本不需要關心太多細節,只需要根據需求編寫實現即可,了解其實現原理,可增強自己的設計思想,現在請一步一步來看下這個過程
首先是客戶端調用就是這么簡單,一個TRORemoteService對象轉成服務端的一個接口,即可調用服務端的接口函數,
其實在程序啟動的時候就已經完成了大多數工作了,先是看下主窗體的文件引用
當在界面擺上以下3個控件
ROMessage: TROBinMessage;
RORemoteService: TRORemoteService;
ROChannel: TROIndyTCPChannel;
會自動引入上圖的文件, 這里的核心文件是 uROClient
先看下其初始化代碼
該代碼主要是創建了針對 消息類,通
道類,代理類 的管理列表對象
當我們使用一種消息格式的類時, 這里以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; 對象
接下來的代碼開始對入參進行指定消息格式的打包
首先是在請求數據頭里寫入要調用服務端接口及函數名稱,然后再以序列化的方式寫入入參數據






這里用到的對象序列化思想,簡單地說就是把一個對象按一定的格式保存到流對象里,這個過程可以理解為 封包
數據按消息類打包后,調用通道類進行傳輸
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, []);
以上這就是整個客戶端的調用過程