1. 程式人生 > >C++ 簡單遠端呼叫中介軟體設計 (三)

C++ 簡單遠端呼叫中介軟體設計 (三)

 今天 “C++ 簡單遠端呼叫” 第三版完成了,現在我叫他 “gcpprc” ,這次主要改進了遠端呼叫過程中引數的打包和解包過程。這次我把 gcpprc 和演示程式的原始碼分成兩組原始檔,這樣 gcpprc 就可以單獨編譯成一個共享庫。我決定 gcpprc 在 lgpl2 協議下發行,對 lgpl 通常的理解是,如果您寫的軟體始終以動態連線的形式連線到這個函式庫,可以不公開原始碼,靜態連線和對庫本身的修改需要公開原始碼。這樣您就可以用 gcpprc 開發商業程式了,我個人認為 gcpprc 可以把一部分網路程式的程式設計難度降低一半以上,如果您需要對 gcpprc 的技術支援和定製開發,我就要考慮收費了。
 
這次釋出的 gcpprc 的演示程式 gcpprccli/gcpprcser 在 gpl2 協議下發行,關於對 gpl/lgpl 的權威解釋請看 http://www.gnu.org/licenses/附件中是 gcpprc 程式原始碼,真正的本人原創。

檔案: gcpprc_03_20070503.tar
大小: 50KB
下載: 下載


注意:正如 gpl 和 lgpl 相關條款中所說的,這個軟體預設沒有擔保。我不能保證 gcpprc 和 gcpprccli/gcpprcser 中沒有錯誤,如果您需要某種程度的擔保或技術支援和定製開發等服務請和我聯絡,我會考慮,不過這些通常要收費。我的 email 是 [email protected] ,還有 [email protected]

    我在以前的部落格文章中說過
gcpprc 的原理不難. 但 gcpprc 比較簡單實用,這也是我的設計目標。這個庫封裝了遠端物件呼叫的大部分操作,包括遠端物件的建立和撤銷,
遠端物件和方法編號註冊,引數的打包和解包,打包後的遠端物件和方法編號和引數資料的網路傳輸等, gcpprc 提供了一組比較容易使用的 C++ 類,我們只需要比較簡單的程式設計就能開發出網路應用程式。gcpprc 服務端有一個通訊類處理 socket 通訊,提供各種服務的服務端物件把自己的指標傳給通訊類的物件,儲存在一個 std::map 中,客戶端的代理物件代表服務端物件接受呼叫,然後把服務端物件類標識,函式標識,函式引數打包傳給服務端,服務端把收到的資料解包,呼叫服務端物件,然後把呼叫結果資料打包傳回客戶端,客戶端把返回的資料解包,最後客戶端代理物件把呼叫結果返回客戶端程式。

    gcpprc 可以為每一個客戶端代理類例項動態建立一個對應的服務端類例項,這樣就可以儲存中間資訊。在演示程式中我用這個功能實現了一個檔案讀寫訪問類。當客戶端代理類的例項初始化時它呼叫服務端物件的 clone 方法,clone 方法建立一個服務端物件的新例項,並把新例項的指標儲存在 std::map 中,用新例項的物件標識做 std::map 中的 key ,並且把這個物件標識返回給客戶端,然後客戶端就可以用這個物件標識呼叫服務端物件了,這時服務端物件和客戶端代理是一對一服務,所以服務端物件可以儲存開啟的檔案物件,檔案讀取指標等中間資訊。當客戶端代理不再需要服務時它呼叫服務端物件的 erase 方法, erase 方法先清除服務端物件在 std::map 中的資訊,然後從記憶體中清除這個物件。如果服務端物件不需要儲存中間資訊,那麼只要有一個例項就行了,客戶端的代理用同一個標識呼叫它。我在演示程式中演示了這種情況,呼叫一個遠端物件做整數的加減法和連線字串。

    gcpprc 系統需求:
           x86-32 相容處理器,Linux 或 win2k/winxp 平臺。目前我沒有處理網路位元組順序問題,但用於 x86-32 機器之間的遠端呼叫程式設計是沒有問題的。運行於 32 位模式的 x86-64 處理器也沒問題,我的機器用的就是 AMD64 處理器, 但作業系統是 32 位的。 Linux 和 win2k/winxp 平臺之間的 gcpprc 程式也可以互相遠端呼叫。 BSD 平臺沒有測試,應該問題不大。

    gcpprc 程式開發環境: Linux 或 win32/mingw 開發環境,需要 gtkmm 開發庫。

    Linux 下編譯命令:
         gcpprc 共享庫: g++ -shared -o  libgcpprc.so gcpprclib.cc  `pkg-config gtkmm-2.4 --cflags --libs` -lgthread-2.0

         gcpprc 演示程式: 
            客戶端 gcpprccli:  g++ -Wall -g -o  gcpprccli  gcpprccli.cc `pkg-config  gtkmm-2.4 --cflags --libs` -lgthread-2.0  -L./  -lgcpprc
 
            伺服器 gcpprcser:  g++ -Wall -g -o  gcpprcser  gcpprcser.cc `pkg-config  gtkmm-2.4 --cflags --libs` -lgthread-2.0  -L./  -lgcpprc
       
         您可能需要: export LD_LIBRARY_PATH="./"  。


    win32/mingw 開發環境下編譯命令:

         gcpprc 共享庫: g++ -shared -o gcpprc.dll gcpprclib.cc -Wl,--out-implib,libgcpprc.a `pkg-config.exe gtkmm-2.4 --cflags --libs` -lgthread-2.0 -lws2_32

         gcpprc 演示程式:

             客戶端 gcpprccli:  g++ -Wall -g -o  gcpprccli  gcpprccli.cc `pkg-config.exe gtkmm-2.4 --cflags --libs` -lgthread-2.0 -lws2_32 -L./ -lgcpprc

             伺服器 gcpprcser:  g++ -Wall -g -o  gcpprcser  gcpprcser.cc `pkg-config.exe gtkmm-2.4 --cflags --libs` -lgthread-2.0 -lws2_32 -L./ -lgcpprc


    gcpprc 程式開發說明:

             客戶端程式開發主要是編寫客戶端代理,客戶端代理物件代表服務端物件接受呼叫。客戶端代理類的基本類是 gcpprc::SerAgent ,SerAgent 實現並封裝了很多客戶端代理的操作,提供了比較簡單的程式設計介面。

             客戶端代理類需要有一個初始化函式 init,  init 函式首先設定物件標識,物件標識包括類標識和類的例項標識兩個部分,客戶端和服務端的類標識是相同的,統一定義在一個頭檔案中,如果服務端類不需要儲存中間資訊,那麼例項標識永遠是 0 , 客戶端代理類的不同例項都呼叫同一個服務端類例項,init 函式設定物件標識後呼叫 SerAgent::init 函式連線到伺服器,如果服務端類需要儲存中間資訊,那麼還要呼叫 clone 函式,clone 會產生一個服務端類的新例項,並把新例項的標識返回客戶端,然後客戶端就可以用新物件標識呼叫服務端例項了。
          
             客戶端代理類還需要實現一組代理函式,代表服務端類的對應函式接受客戶端程式的呼叫。這些代理函式呼叫 SerAgent::remote_call 函式和服務端通訊,SerAgent::remote_call 的第一個引數是函式標識,客戶端和服務端的函式標識和類標識統一定義在一個頭檔案中,統一的函式標識和類標識是客戶端和服務端為實現遠端呼叫所做的約定。remote_call 的其他引數是代理函式要傳給服務端函式的引數資料的地址,remote_call 會把資料打包傳給服務端,完成遠端呼叫後再把服務端返回的資料解包返回給客戶端代理函式,SerAgent::remote_call 是 gcpprc 最重要的部分。

             服務端程式開發主要是編寫各種服務端服務模組類,服務端程式啟動時要建立一個 gcpprc::CommunicateSer 的例項, CommunicateSer 是 gcpprc 中處理服務端網路通訊的類,服務端服務模組類的例項需要呼叫 CommunicateSer::reg_server 函式,把自己的指標註冊到 CommunicateSer 中的一個 std::map<guint64, ModuleServer*> 中,然後 CommunicateSer 開始監聽客戶端的連線請求,CommunicateSer 會為每一個客戶端連線建立一個新執行緒,然後在新執行緒中根據客戶端傳來的物件標識呼叫不同的服務端類例項的 call_switch 函式, call_switch 函式把客戶端傳來的引數資料解包, 然後根據函式標識呼叫各個具體的服務函式,把呼叫結果返回 CommunicateSer , 最後 CommunicateSer 把呼叫結果返回客戶端。為了能用函式標識呼叫服務端類例項的函式,服務端類要實現一個初始化函式 init , 服務端類例項呼叫 init 函式把各個服務函式的指標儲存到自己的 std::map<guint32, P_FUNC> 中 , std::map 的 key 就是函式標識.      

class SerAgent
{
    protected:
    struct sockaddr_in sa;
    struct sockaddr_in sa_serv;
    struct sockaddr_in sa_cli;

    char data_buf[PACK_SIZE];
    IdObj id_obj;
    int err;
    int listen_sd;
    int sd;
    int client_len;

    public:
        gint32 init(char *ap_server_ip, gint32 a_port);    
    gint32 call_ser(char* ap_data);
    void close_socket();

    protected:
    int remote_call(guint32 a_func_id, PAny pa = (char*)0 , PAny pb = (char*)0, PAny pc = (char*)0,
             PAny pd = (char*)0, PAny pe = (char*)0, PAny pf = (char*)0, PAny pg = (char*)0,
             PAny ph = (char*)0, PAny pi = (char*)0, PAny pj = (char*)0);
};

class ModuleServer
{
    protected:
    Glib::Mutex mutex_map;

    protected:
    typedef void (ModuleServer::*P_FUNC)(char *ap_data, char *ap_a, char *ap_b, char *ap_c,
                     char *ap_d, char *ap_e, char *ap_f, char *ap_g,
                     char *ap_h, char *ap_i, char *ap_j);

    P_FUNC p_func;

    std::map<guint32, P_FUNC> map_func;
    std::map<guint32, P_FUNC>::iterator it_map_func;
 
    typedef std::pair<guint32, P_FUNC> Ps_Func;

    protected:
        void reg_func(guint32 a_id_func, P_FUNC a_pfunc);    
    void find_function_error(char *ap_data);
    void unpack_data(char *ap_data, char **pp_ch);
    void fix_size_of_data(char *ap_data, gint32 a_fix_size);

    public:
    void call_switch(char *ap_data);        
};



                                                              朱江
                                                         2007.05.04
http://blog.chinaunix.net/u/21585/showart_290864.html

相關推薦

C++ 簡單遠端呼叫中介軟體設計 ()

 今天 “C++ 簡單遠端呼叫” 第三版完成了,現在我叫他 “gcpprc” ,這次主要改進了遠端呼叫過程中引數的打包和解包過程。這次我把 gcpprc 和演示程式的原始碼分成兩組原始檔,這樣 gcpprc 就可以單獨編譯成一個共享庫。我決定 gcpprc 在 lgpl2 協

C++ 簡單遠端呼叫中介軟體設計

   我寫過一些 socket 程式, 隨著程式的逐步複雜,直接用 socket 程式設計顯得有些麻煩。根據軟體應該模組化的思想,應該把軟體中的 socket 通訊部分相對獨立出來做成一個“中介軟體”。我用 C++ 寫了一個最簡單的“遠端呼叫中介軟體” 原理演示程式, 共享出來和大家討論(本人水平有限,如有錯

遠端呼叫中介軟體(RPC)

RPC 是指計算機 A 上的程序,呼叫另外一臺計算機 B 上的程序,其中 A 上的呼叫程序被掛起,而 B 上的被呼叫程序開始執行,當值返回給 A 時,A 程序繼續執行。呼叫方可以通過使用引數將資訊傳送

遠端過程呼叫中介軟體及資料訪問中間…

一 實習目的 通過例項掌握RMI,RPC,JDBC等中介軟體的使用。 二 實習要求 1)RPC實現遠端計算服務。伺服器端提供計算服務;客戶端呼叫計算服務。 2)RMI+JDBC遠端資料庫的訪問。實現簡單的成績查詢系統(建立表,錄入成績,查詢成績等)。在伺服器端,通過JDBC訪問資料庫。客戶端呼叫服

如何設計一個簡單的訊息中介軟體

​前言 我們日常開發當中需要用到訊息中介軟體的場合很多,我們或許也用到了形形色色的訊息中介軟體產品,有老牌的ActiveMQ、RabbitMQ,炙手可熱的Kafaka,還有阿里研發的Notify、MetaQ、RocketMQ等等,但反過來思考一下,如果讓我們自己來設計一個訊息中介軟體,需要考慮哪些方面的問題,

交易環節訊息中介軟體設計——去哪兒餘昭輝

交易環節訊息中介軟體 問題考慮 不能丟訊息 丟訊息意味著掉單,意味著支付成功但是沒給人家出票,這是不能接受的。 穩定 訊息中介軟體一旦出問題,交易不能進行,也是嚴重的故障。 效能 典型的訊息中介軟體包含 3 部分 producer(釋出者)、broker(訊息中

騰訊 VS 阿里 VS 攜程訊息中介軟體設計方案及思路

原文連結:https://blog.csdn.net/lizhitao/article/details/51718156 背景 目前我們美團正在設計和不斷迭代、升級訊息中介軟體方案,為了避免走彎路,希望站在巨頭肩膀上,學習經驗、吸取精華,推動美團MQ快速演進,為美團業務高速擴張提供支撐 目標

徹底搞懂Scrapy的中介軟體

在前面兩篇文章介紹了下載器中介軟體的使用,這篇文章將會介紹爬蟲中介軟體(Spider Middleware)的使用。 爬蟲中介軟體 爬蟲中介軟體的用法與下載器中介軟體非常相似,只是它們的作用物件不同。下載器中介軟體的作用物件是請求request和返回response;爬蟲中介軟體的作用物件是爬蟲,更具體地

中介軟體系列 RabbitMQ之交換機的四種類型和屬性

<div class="markdown_views prism-atom-one-dark"> &

訊息佇列中介軟體)Kafka 入門指南

Kafka 來源 Kafka的前身是由LinkedIn開源的一款產品,2011年初開始開源,加入了 Apache 基金會,2012年從 Apache Incubator 畢業變成了 Apache 頂級開源專案。同時LinkedIn還有許多著名的開源產品。如: 分散式資料同步系統Databus

Spring 與Hessian 整合的簡單遠端呼叫例項

這幾天一直在學習遠端呼叫只是,今天學習spring與hessian整合釋出遠端服務,研究了一天,各種錯誤,各種網上找答案。皇天不負有心人,總算整合出一個簡單的demo。不多說直接,來點有營養的! 因為Hessian是基於Http協議的框架,所以服務端是一

應用訊息中介軟體設計可以解決哪些實際問題?

訊息佇列中介軟體是分散式系統中重要的元件,主要解決應用解耦,非同步訊息,流量削鋒等問題,實現高效能,高可用,可伸縮和最終一致性架構。目前使用較多的訊息佇列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。訊息中介軟體到底該如何使用,何時使用這是一

c#開源訊息佇列中介軟體EQueue 教程

一、簡介 EQueue是一個參照RocketMQ實現的開源訊息佇列中介軟體,相容Mono,具體可以參看作者的文章《分享一個c#寫的開源分散式訊息佇列equeue》。專案開源地址:https://github.com/tangxuehua/equeue,專案中包含了佇列

架構設計:一種遠端呼叫服務的設計構思(zookeeper的一種應用實踐)

在深入學習zookeeper我想先給大家介紹一個和zookeeper相關的應用例項,我把這個例項命名為遠端呼叫服務。通過對這種應用例項的描述,我們會對zookeeper應用場景會有深入的瞭解。   遠端呼叫是系統與系統之間的通訊機制,它的另一種理解就是程序間的通訊。做分散式

Java中介軟體JMS()之ActiveMQ整合spring監聽器(二)

對於讓spring管理監聽的實現方式有兩種方法,一種是自己寫監聽器,然後交給spring的監聽介面卡管理,再由監聽容器管理監聽介面卡,另一種是寫一個實現MessageListener介面的類。第一種在第一章涉及到,但是沒有交給spring託管.其實實現的方法很簡單,在j2e

高效能可伸縮的分散式訊息中介軟體設計

訊息中介軟體基本上是每一個大型網際網路公司的標準基礎技術元件配置,雖然有很多的開源訊息中介軟體,功能也很強大,但是今天我還是想介紹一下怎樣自主架構與設計並實現一套完整的分散式訊息中介軟體。開源的訊息中介軟體或多或少存在一些所謂“坑”,沒有遇到大家用得都很happy,遇到的同學

C#的遠端呼叫與Java的RMI借鑑學習

這兩天一直在溫習C#的遠端呼叫。VS2008帶的MSDN中的說明有點亂,示例程式碼也不全,好不容易終於在微軟的MSDN上找到了遠端呼叫的相關資料。不過示例程式碼裡就只是幾句有關配置的程式碼(RemotingConfiguration.Config),搞得我暈暈乎乎。再結合前面的TcpServerChann

Laravel5.1註冊中介軟體種場景

在Laravel中註冊中介軟體主要有三種場景,一種給控制器中的方法進行註冊,一種是給整個控制器進行註冊,最後一種是給全域性註冊中介軟體。 1、在控制器中的方法中註冊中介軟體 這種需求是最為常見,這個例子是給IndexController中的inde

dubbo遠端呼叫原始碼分析():客戶端接收反饋後的處理

dubbo遠端呼叫的原始碼分析,分成了三篇文章地址分別如下:下面是consumer接收到provider反饋時的處理consumer接收到provider的反饋後,觸發NettyClient的事件處理器,該事件對consumer來說是上行事件,觸發的是NettyCodecAd

遠端呼叫框架】如何實現一個簡單的RPC框架(五)優化:軟負載中心設計與實現

【如何實現一個簡單的RPC框架】系列文章: 1.前言 在部落格【遠端呼叫框架】如何實現一個簡單的RPC框架(一)想法與設計中我們介紹了“服務註冊查詢中心”,負責服務資訊的管理即服務的註冊以及查詢,在目前為止的實現中,我們採用web應用的方式,以