gSoap

gSOAP編譯工具提供了一個SOAP/XML 關於C/C++ 語言的實現,從而讓C/C++語言開發web服務或客戶端程式的工作變得輕鬆了很多。絕大多數的C++web服務工具包提供一組API函式類庫來處理特定的SOAP數據結構,這樣就使得用戶必須改變程式結構來適應相關的類庫。與之相反,gSOAP利用編譯器技術提供了一組透明化的SOAP API,並將與開發無關的SOAP實現細節相關的內容對用戶隱藏起來。

gSOAP的編譯器能夠自動的將用戶定義的本地化的C或C++數據類型轉變為符合XML語法的數據結構,反之亦然。這樣,只用一組簡單的API就將用戶從SOAP細節實現工作中解脫了出來,可以專注與應用程式邏輯的實現工作了。gSOAP編譯器可以集成C/C++和Fortran代碼(通過一個Fortran到C的接口),嵌入式系統,其他SOAP程式提供的實時軟體的資源和信息;可以跨越多個作業系統,語言環境以及在防火牆後的不同組織。
gSOAP使編寫web服務的工作最小化了。gSOAP編譯器生成SOAP的代碼來序列化或反序列化C/C++的數據結構。gSOAP包含一個WSDL生成器,用它來為你的web服務生成web服務的解釋。gSOAP的解釋器及導入器可以使用戶不需要分析web服務的細節就可以實現一個客戶端或服務端程式。
下面是gSOAP的一些特點:
×gSOAP編譯器可以根據用戶定義的C和C++數據結構自動生成符合SOAP的實例化代碼。
×gSOAP支持WSDL 1.1, SOAP 1.1, SOAP 1.2, SOAP RPC 編碼方式以及 literal/document 方式.
×gSOAP是少數完全支持SOAP1.1 RPC編碼功能的工具包,包括多維數組及動態類型。比如,一個包含一個基類參數的遠程方法可以接收客戶端傳來的子類實例。子類實例通過動態綁定技術來保持一致性。
×gSOAP 支持 MIME (Swa) 和 dime 附屬檔案包。
×gSOAP是唯一支持DIME附屬檔案傳輸的工具包。它允許你在保證XML可用性的同時能夠以最快的方式(流方式)傳遞近乎無大小限制的二進制數據。
×gSOAP 支持 SOAP-over-UDP。
×gSOAP 支持 IPv4 and IPv6.
×gSOAP 支持 Zlib deflate and gzip compression(for HTTP, TCP/IP, and XML file storage)。
×gSOAP 支持 SSL (HTTPS)。
×gSOAP 支持 HTTP/1.0, HTTP/1.1 保持連線, 分塊傳輸及基本驗證。
×gSOAP 支持 SOAP 單向訊息。
×gSOAP 包含一個 WSDL 生成器,便於web服務的發布。
×gSOAP 包含一個WSDL解析器(將WSDL轉換為gSOAP頭檔案),可以自動化用戶客戶端及服務端的開發。
×生成可以單獨運行的web服務及客戶端程式。
×因為只需要很少記憶體空間,所以可以運行在類似Palm OS, Symbian, Pocket PC的小型設備中。
×適用於以C或C++開發的web服務中。
×跨平台:Windows, Unix, Linux, Mac OS X, Pocket PC, Palm OS, Symbian等。
×支持序列化程式中的本地化C/C++數據結構。
×可以使用輸入和輸出緩衝區來提高效率,但是不用完全訊息緩衝來確定HTTP訊息的長度。取而代之的是一個三相序列化方法。這樣,像64位編碼的圖像就可以在小記憶體設備(如PDA)中以DIME附屬檔案或其他方式傳輸。
×支持C++單繼承,動態綁定,重載,指針結構(列表、樹、圖、循環圖,定長數組,動態數組,枚舉,64位2進制編碼及16進制編碼)。
×不需要重寫現有的C/C++套用。但是,不能用unions,指針和空指針來作為遠程方法調用參數的數據結構中元素。
×三相編組:1)分析指針,引用,循環數據結構;2)確定HTTP訊息長度;3)將數據序列化位SOAP1.1編碼方式或用戶定義的數據編碼方式。
×雙相編組:1)SOAP解釋及編碼;2)分解“forward”指針(例如:分解SOAP中的href屬性)。
×完整可定製的SOAP錯誤處理機制。
×可定製的SOAP訊息頭處理機制,可以用來保持狀態信息
2 gSoap2.2版與gSOAP 2.1版(或以前版本)的不同
如果你是從2.1版升級到2.2或以後版本,請注意這些變化。
為了能夠分離傳輸、內容編碼、映射中的接收/傳送設定,改變了運行時選項及標誌。這些標誌分布再四個類中:傳輸(IO),內容編碼(ENC),XML編組(XML)及C/C++數據映射。不再提倡使用舊標誌soap_disable_X及soap_enable_X(其中,X表示選項名)。具體內容請參見9.12節。
3. gSoap2.x版與gSOAP 1.x版的不同
如果你是從1.x版升級到2.x版,請注意下面的內容。
gSOAP2.0及之後的版本是在1.x版基礎上重寫的。gSOAP2.0之後的版本是執行緒安全的,但之前版本不是。gSOAP2.x版本中的主要檔案已經重新命名,以便與1.x版區分。
gSOAP 1.X gSOAP 2.X
soapcpp soapcpp2
soapcpp.exe soapcpp2.exe
stdsoap.h stdsoap2.h
stdsoap.c stdsoap2.c
stdsoap.cpp stdsoap2.cpp
從1.x版升級到2.x版並不需要進行大量的代碼重寫工作。所有2.x版相關的函式都定義在stdsoap2.c[pp]檔案中,這個檔案是由gSOAP編譯器自動生成的。所以,用1.x版開發的服務端或客戶端代碼需要進行修改以適應2.x版中函式的變化:在2.x版中,所有的gSOAP函式都增加了一個參數用來保存一個gSOAP運行環境實例。這個參數包括了檔案描述,表,緩衝,標誌位等,它在所有gSOAP函式中都是第一個參數。
gSOAP運行環境實例是一個struct soap類型的變數。當客戶端程式訪問遠程方法前或當服務端程式能夠接收一個請求前,必須先將這個運行環
境變數初始化。在2.x版中新增了3個函式來負責這些事情:
函式 解釋
soap_init(struct soap *soap) 初始化環境變數(只需執行一次)
struct soap *soap_new() 定義並初始化環境變數並返回一個該變數的指針
struct soap *soap_copy(struct soap *soap) 定義一個環境變數並從已有的環境變數中拷貝環境信息
環境變數定義好後就可以重複使用而不必再次初始化了。只有當執行緒獨占訪問時,我們才需要一個新的環境變數。例如,下面的代碼分配了
一個用於多個遠程方法的環境變數:
int main()
{
struct soap soap;
...
soap_init(&soap); // 初始化環境變數
...
soap_call_ns__method1(&soap, ...); // 調用一個遠程方法
...
soap_call_ns__method2(&soap, ...); // 調用另一個遠程方法
...
soap_end(&soap); // 清除環境變數
...
}
我們也可以像下面這樣定義環境變數:
int main()
{
struct soap *soap;
...
soap = soap_new(); // 定義並初始化環境變數
if (!soap) // 如果不能定義,退出
...
soap_call_ns__method1(soap, ...); // 調用遠程函式
...
soap_call_ns__method2(soap, ...); // 調用另一個遠程函式
...
soap_end(soap); // 清除環境變數
...
free(soap); // 釋放環境變數空間
}
服務端代碼在調用soap_serve函式前,需要定義相關環境變數:
int main()
{
struct soap soap;
soap_init(&soap);
soap_serve(&soap);
}
或者像下面這樣:
int main()
{
soap_serve(soap_new());
}
soap_serve函式用來處理一個或多個(當允許HTTP keep-alive時,參見18.11節中的SOAP_IO_KEEPALIVE標誌)請求。
一個web服務可以用多執行緒技術來處理請求:
int main()
{
struct soap soap1, soap2;
pthread_t tid;
...
soap_init(&soap1);
if (soap_bind(&soap1, host, port, backlog) < 0) exit(1);
if (soap_accept(&soap1) < 0) exit(1);
pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1);
...
soap_init(&soap2);
soap_call_ns__method(&soap2, ...); // 調用遠程方法
...
soap_end(&soap2);
...
pthread_join(tid, NULL); // 等待執行緒結束
soap_end(&soap1); // 釋放環境變數
}
在上面的例子中,需要兩個環境變數信息。而在1.x版本中,由於靜態分配環境變數,多執行緒技術是不被允許的(只有一個執行緒可以用這個環
境變數調用遠程方法或處理請求信息)。
4 準備工作
要開始用gSOAP創建一個web服務套用, 你需要:
一個C/C++編譯器.
擁有根據作業系統平台創建的可執行的gSOAP的stdsoap2(windows下為stdsoap2.exe)編譯器。
擁有根據作業系統平台創建的可執行的gSOAP的wsdl2h(windows下為wsdl2h.exe)WSDL解析器。
需要'stdsoap2.c'或'stdsoap2.cpp'及'stdsoap2.h'檔案來實現你的SOAP功能。你可以創建一個dll或動態庫以便簡化連線。
如果你要支持SSL(HTTPS)及壓縮的話,可以安裝openssl及Zlib庫。
gSOAP是獨立開發包,不需要任何第三方的軟體支持(除非你要用到OpenSSL及Zlib)。
與平台無關的gSOAP版本需要你下面的工具編譯'soapcpp2'及'wsdl2h'檔案:
一個C++編譯器(用來編譯'wsdl2h'WSDL解析器)。
Bison 或 Yacc
Flex 或 Lex
推薦使用Bison及Flex。
在軟體包samples目錄下有大量的開發實例。可以用'make'來編譯這些例子。這些例子包含了gSOAP中的各個方面。其中,最簡單的例子是
one-liners(samples/oneliners)。
5 快速指南
本指南旨在讓你快速開始你的gSOAP開發之旅。閱讀本節的內容,需要你對SOAP 1.1協定及C/C++語法有大體的了解。雖然使用gSOAP編譯器可
以直接用C/C++開始編寫web服務及客戶端程式而不需要了解Soap協定的細節,但是由於我們在本節中使用了大量的實例來說明gSOAP與其他SOAP
實現的連線及通訊,所以了解一些SOAP及WSDL協定也是必需的。
5.1 如何使用gSOAP編譯環境來編譯SOAP客戶端程式
通常,一個SOAP客戶端套用的實現需要為每個客戶端需要調用的遠程方法提供一個存根例程(stub routine)。存根例程主要負責編碼參數信息;將包含參數信息的調用請求傳送給制定的SOAP服務;等待返回結果;將結果中的參數信息編碼。客戶端程式調用訪問遠程方法的存根例程
就像調用本地方法一樣。用C/C++手工別寫一個存根例程是個十分痛苦的差使,尤其當遠程方法的參數中包含特定的數據結構(如:記錄、數組、圖等)時。幸運的是,gSOAP包中的'wsdl2h'WSDL解析器和'soapcpp2’存根及架構編譯器能夠將web服務客戶端及服務端的開發工作自動化。
'soapcpp2’存根及架構編譯器是可以生成構建C++ SOAP客戶端所需的C++源碼的預編譯器。該預編譯器的輸入參數是一個標準的C/C++頭檔案。這個頭檔案可以由WSDL解析器根據相關的WSDL文檔自動生成。
參見下面的命令:
$ wsdl2h -o quote.h
上面的命令根據制定URL提供的WSDL文檔生成一個C++語法結構的頭檔案。
如果需要生成一個純C的頭檔案,需要一下命令:
$ wsdl2h -c -o quote.h
更多關於WSDL解析器及其選項的細節信息,請參見8.2.10節。
執行上述命令後,quote.h檔案就生成了。其中包含開發客戶端或服務端程式的存根例程定義。SOAP服務遠程方法以函式聲明的方式在這個頭檔案中被定義。C/C++原始碼的存根例程將通過預編譯器自動實現。同時,每個遠程方法的程式框架也被自動生成了,它可以用來建立SOAP服務端程式套用。
SOAP服務的輸入輸出參數可以是簡單的數據類型或複雜的數據結構,可以由WSDL解析器自動生成或手工定義。預編譯器將自動生成序列化/反序列化這些數據的代碼,以便存根例程可以將這些數據以XML的方式編碼或解碼。

相關詞條

相關搜尋

熱門詞條

聯絡我們