c/c++的Soap應用


1. 關於soap

      在許多項目中團隊中,我們常常會聽到這樣的話:我們這里是用webservice交互的。而說話的場景往往就是交互對象雙方比較異構,所謂異構、即雙方是不同的開發語言、不同的運行環境等。比如常見的c/c++后台程序與java的web程序間的通信,當然這里的通信是網絡通信,如果是一體化單機系統內,可能第一反應是JNI方式了。

      異構體系間的通信,就是webservice的基本應用場景。而soap(simple object access protocal)則是webservice在實際操作中需要遵守的協議,webservice的其它關鍵元素還有:WSDL, http, xml等。

2. 適用情況

      如前所述、在一個項目中不同開發體系間希望交互信息,同時不願花大氣力自己做通信框架,產品需求定位為:快捷開發、穩定有效,沒有明顯大並發的需求,那么webservice是一個很好的選擇。

      之所以排除大並發的應用場景,個人覺得大並發平台網絡環境復雜,在接口伸縮性和業務結合度方面,一般都是公司內部封裝通信框架更合適。另外webservice通信中攜帶的冗余信息太多也是一大詬病,所以大並發的場景,想想也算了。

3. C++ gsoap工具

      Gsoap是c/c++在webservice開發中一個強大工具,c/c++er在做webservice開發一般都是用的這個利器。

      從網上很容易找到gsoap的源碼,以我下載的gsoap-2.8為例。如果不用特別的研究編譯工具源碼,那么下載后需要用的東西是兩個地方:

      1. 在\gsoap-2.8\gsoap\bin\win32目錄下有兩個編譯工具:wsdl2h.exe和soapcpp2.exe。

    wsdl2h.exe:用於將wsdl文件轉換為c/c++使用的頭文件。

    soapcpp2.exe:用於將上述頭文件轉換為c/c++項目使用的基礎代碼。包括客戶端代碼、服務端代碼、頭文件的wsdl描述。

      2. 在\gsoap-2.8\gsoap目錄下有兩個文件:stdsoap2.cpp和stdsoap2.h。這兩個文件即為c++使用webservice通信的底層soap協議實現。

4. C++應用

      對於C++來說,webservice就是一種RPC(Remote Procedure Call Protocol遠程過程調用協議)方式,既然是RPC,通俗的說、就是本地C++需要用到異地環境的方法,那么本地與異地雙方就有一個基本的方法列表,之后達到就像在調用本地方法一樣的調用異地方法。由此引出C++在webservice開發的基本過程:

      C++服務端開發:

      1)列出能夠提供的方法接口,寫入頭文件;

      2) 用gsoap的soapcpp2.exe編譯工具將1)中頭文件編譯生成服務端代碼;

      3) 將2)中生成的代碼引入到自己的服務端項目中,進行服務端業務開發,需要注意的是服務端必須實現1)中頭文件定義的方法。

      c++客戶端開發:

      1) 如果有服務方提供的wsdl文件,則用gsoap提供的wsdl2h.exe工具生成頭文件,然后同c++服務端開發的前兩步一樣,生成客戶端代碼;

          如果C/S雙方都是C++開發,那么可以不需要wsdl的“介紹”,直接在上述c++服務端開發2)中,同時生成客戶端代碼,拿到這里用即可。

      2) 將上述gsoap框架下的客戶端代碼引入到自己的客戶端項目中,就可以調用服務端方法了。

      歸納:

      C++的webservice開發,如果自己玩,可以不需要wsdl,但如果與其它體系一起協同通信,就需要wsdl(網絡服務描述語言)來描述頭文件的那些方法列表。Soap協議使得通信雙方不需要關心具體通信實現,雙發維護好提供業務的方法即可。

      Gsoap是一個開源的soap封裝,從stdsoap2.cpp中可以看出其跨平台的實現,比如“#ifdef WIN32”這樣的痕跡。stdsoap2.h中代碼風格有值得學習的地方,比如條件預處理格式等,一個頭文件和一個cpp就實現了soap的協議封裝,短小精悍。\gsoap-2.8\gsoap\doc中文檔介紹朴素簡潔,建議以html方式查看,一目了然。

5. 簡單例子

      本例子通過服務端提供一個字符串置反的方法,運行后在本機通過SoapUI測試客戶端調用。

      C++服務端:

      服務端工程,根據前面所述C++服務端開發步驟,首先給出頭文件reverse.h

int ns__reversestr(char *iStr, char **oStr);

      然后就只有一個main.cpp

#include "soapService.h" 

//服務方法的實現

int Service::reversestr(char *iStr, char **oStr)

{

    if (NULL == iStr || NULL == oStr)

    {

       return this->error;

    }

    int strLen = strlen(iStr);

    *oStr = (char*)soap_malloc(this, strLen + 1);

    memset(*oStr, 0, strLen + 1);

    char *pOutBuf = *oStr;

    while (strLen-- > 0)

    {

       *(pOutBuf++) = *(iStr + strLen);

    }

    return this->error;

//服務入口,這里是最基本的服務形式

int main()

{

    Service serv;

    serv.serve();

    int port = 80;  //服務端口,啟用前先用netstat查看下該端口是否被占用

    if (serv.run(port))

    {

       serv.soap_stream_fault(std::cerr);

       exit(-1);

    }

    return 0;

}

      SoapUI測試:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM