一. 按照原來預(yù)研究的結(jié)果拔恰,使用gsoap的方法如下:
- wsdl2h.exe -o weather.h http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsd生成
weather.h文件拒名。 - soapcpp2.exe -C weather.h -I E:\temp\gsoap-2.8\gsoap\import(E:\temp\gsoap-2.8\gsoap\import是我本地的路徑)闰蛔,這樣可以生成C++文件(soapClient.cpp, soapH.h, soapStub.h, WeatherWebServiceSoap.nsmap),然后還需要stdsoap2.cpp和stdsoap2.h 2個(gè)文件卖局,編譯的時(shí)候把這些文件加到工程中。調(diào)用的方法會(huì)在soapStub.h 頭文件中產(chǎn)生茅坛。
參照了以后幾個(gè)wiki:
c++ 通過 gsoap實(shí)現(xiàn) webservice(附帶天氣實(shí)現(xiàn)的例子)
C++訪問WebService(gSoap方式和com組件方式)
C++訪問WebService(gSoap方式和com組件方式)
二. 以上步驟我本地測(cè)試網(wǎng)上公開的天氣接口案怯,證明是可用的,后面第三方接口提供了江场,我安裝以上方法去使用第三方的webservice接口纺酸,發(fā)現(xiàn)一些問題:
- 編譯的時(shí)候出現(xiàn)找不到"stdafx.h"
解決:通過在響應(yīng)的.cpp中最開始添加#include "stdafx.h",修復(fù)該編譯錯(cuò)誤 - 編譯時(shí)遇到 stdsoap2.obj : error LNK2001: 無法解析的外部符號(hào)_namespaces
解決: stdsoap2.h址否,添加
#ifndef WITH_NONAMESPACES #define WITH_NONAMESPACES #endif
三. 以上問題解決后餐蔬,又遇到一個(gè)更奇葩的問題碎紊,因?yàn)橐{(diào)用第三方的二個(gè)接口,但是這二個(gè)接口確實(shí)二個(gè)不同的webservice樊诺,最開始我采取了比較普通的方法仗考,按照gsoap的方法分別操作了二次,并且把這二次生成的文件放在了二個(gè)目錄中词爬,在工程中也是按照這樣的結(jié)構(gòu)添加文件秃嗜,但是
編譯的時(shí)候出問題"error C2374: “namespaces”: 重定義;多次初始化 gsoap",首先我就是谷歌了顿膨,按照一些搜索到的方法去做了锅锨,發(fā)現(xiàn)還是不行,造成這個(gè)問題的原因是因?yàn)槭褂枚鄠€(gè)webservice恋沃,每個(gè).nsmap中都會(huì)定義struct Namespace必搞,造成了重定義,怎么辦呢囊咏?
解決: 后面找了些文章恕洲,發(fā)現(xiàn)我們可以將多個(gè)wsdl文件統(tǒng)一生成為一個(gè)頭文件,然后再用這個(gè)統(tǒng)一的頭文件來生成gsoap代碼則不會(huì)有沖突問題了(解救了我啊)梅割,方式是:
wsdl2h -o file.h file1.wsdl file2.wsdl file3.wsdl‘然后在執(zhí)行【一】中的【2】,生成C++文件霜第,這樣做了后,生成了C++文件炮捧,然后加到項(xiàng)目中,編譯惦银,成功咆课,小開心了一下,然后繼續(xù)去測(cè)試能否獲取到數(shù)據(jù)扯俱。測(cè)試的時(shí)候發(fā)現(xiàn)一直沒有獲取到數(shù)據(jù)书蚪,跟了下代碼,發(fā)現(xiàn)返回調(diào)用公共的接口返回415錯(cuò)誤迅栅,谷歌了下殊校,發(fā)現(xiàn)是因?yàn)閟ervice端只支持 soap 1.1,而gsoap生成客戶端代碼默認(rèn)是1.2
解決: gsoap 的soapcpp2的參數(shù) -1 為soap 1.1 -2為soap1.2,具體就是把【一】【2】中的soapcpp2.exe -C weather.h -I E:\temp\gsoap-2.8\gsoap\import改成soapcpp2.exe -1 -C weather.h -I E:\temp\gsoap-2.8\gsoap\import,這樣就支持soap1.1了读存。改了之后再測(cè)試为流,發(fā)現(xiàn)一直返回12錯(cuò)誤,崩潰~~~让簿,網(wǎng)上找了好多敬察,也沒發(fā)現(xiàn)是什么問題。
為了解決問題尔当,繼續(xù)找啊莲祸,發(fā)現(xiàn)一個(gè)blog:gSoap編寫代碼訪問WCF服務(wù),發(fā)現(xiàn)這個(gè)博主使用的是代理類的形式,我想反正我那條路已經(jīng)斷了,要不也參照下這個(gè)blog試一下吧锐帜,說干就干田盈,參照這,把gsoap的操作改成一下方式了:
wsdl2h.exe -v -o test.h WebService1.wsd WebService2.wsd
soapcpp2.exe -1 -C -j -I E:\temp\gsoap-2.8\gsoap\import test.h
然后把XXXProxy.cpp中的方法中的soap_endpoint的值改一下缴阎,為什么要改呢允瞧?因?yàn)槟J(rèn)gsoap會(huì)將所有的service的endpoint加在一起賦值給每個(gè)接口,這樣就會(huì)出現(xiàn)類似
soap_endpoint=
"http://10.32.4.20:8012/QueryInterface.asmxhttp://10.32.4.20:9988/CommonService.svc";
的形式,其實(shí)我們需要的是
soap_endpoint = "http://10.32.4.20:8012/QueryInterface.asmx";
所以需要手動(dòng)去把有類似問題的都改一下药蜻,改好后再重新編譯瓷式,OK,都沒有問題语泽,繼續(xù)測(cè)試贸典,OMG,完美踱卵,可以正常訪問廊驼,心里終于舒坦了。
四. gsoap設(shè)置超時(shí)
- 修改gsoap自動(dòng)生成的代碼才能進(jìn)行超時(shí)設(shè)置(我這邊訪問web service的代碼都是gsoap工具自動(dòng)生成.根據(jù)wsdl接口)
- 找到生成的soapwwwsdlBindingProxy.cpp文件
- 找到你要設(shè)置超時(shí)的那個(gè)調(diào)用服務(wù)器的方法
- 找到該方法代碼 struct soap *soap = this;
在該代碼下添加如下三行代碼(時(shí)間大小根據(jù)項(xiàng)目自行調(diào)整)
soap->recv_timeout = 2;//接受 (單位是秒)
soap->send_timeout = 2;//發(fā)送 (單位是秒)
soap->connect_timeout = 2;//連接(單位是秒)
--以上就是這次通過gsoap使用webservice的全部過程惋砂,記錄下來妒挎,方便自己以后查閱,也希望對(duì)遇到同樣問題的你西饵,有所幫助酝掩。
以上有參考一下wiki:
gsoap之client端引用多個(gè)service時(shí)命名沖突
gsoap 調(diào)用 WCF 415 錯(cuò)誤