Web Service与gSoap
什么是Web Service?
对于这个问题,估计题主不能给出大家满意的答案,毕竟不是专门搞网络开发的,只是现有工作需要在桌面客户端和服务器端进行数据交互通讯,才用到Web Service。下面粘出一些在网上摘的内容,大家自行揣摩:
- Web Services 是应用程序组件
- Web Services 使用开放协议进行通信
- Web Services 是独立的(self-contained)并可自我描述
- Web Services 可通过使用UDDI来发现
- Web Services 可被其他应用程序使用
- XML 是 Web Services 的基础
题主理解如下:
为了解决桌面客户端程序与服务器的通信问题,需要在服务器上部署一个应用程序,它能够对外界暴露一个能够通过Web进行调用的API,即能够用编程的方法通过Web来调用这个应用程序。这个部署在服务器上的应用程序就是Web Service。
举个栗子,你的桌面应用程序想要从服务器上获取天气信息,就可以在服务器上创建一个Web service ,它的作用是返回当前的天气情况。你可以建立一个ASP页面,它接受邮政编码作为查询字符串,然后返回一个由逗号隔开的字符串,包含了当前的气温和天气。这个ASP页面就可以算作是Web service 了。因为它基于HTTP GET请求,暴露出了一个可以通过Web调用的API。
什么是WSDL?
以下摘自百度百科:
你会怎样向别人介绍你的Web service有什么功能,以及每个函数调用时的参数呢?你可能会自己写一套文档,你甚至可能会口头上告诉需要使用你的Web service的人。这些非正式的方法至少都有一个严重的问题:当程序员坐到电脑前,想要使用你的Web service的时候,他们的工具(如Visual Studio)无法给他们提供任何帮助,因为这些工具根本就不了解你的Web service。
解决方法是:用机器能阅读的方式提供一个正式的描述文档。Web service描述语言(WSDL)就是这样一个基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web service及其函数、参数和返回值。WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应Web service的代码。
什么是gSoap?
下面进入到最重要的点了,编程语言怎么调用Web Service函数呢?
以下摘自百度百科:
Web service建好以后,你或者其他人就会去调用它。简单对象访问协议(SOAP)提供了标准的RPC方法来调用Web service。实际上,SOAP在这里有点用词不当:它意味着下面的Web service是以对象的方式表示的,但事实并不一定如此:你完全可以把你的Web service写成一系列的C函数,并仍然使用SOAP进行调用。SOAP规范定义了SOAP消息的格式,以及怎样通过HTTP协议来使用SOAP。SOAP也是基于XML(标准通用标记语言下的一个子集)和XSD的,XML是SOAP的数据编码方式。
这里主要说一下gSoap,题主工作项目中是用gSoap将WebService API转成C++可调用的接口。
以下摘自百度百科:
gSOAP编译工具提供了一个SOAP/XML 关于C/C++ 语言的实现,从而让C/C++语言开发web服务或客户端程序的工作变得轻松了很多。绝大多数的C++web服务工具包提供一组API函数类库来处理特定的SOAP数据结构,这样就使得用户必须改变程序结构来适应相关的类库。与之相反,gSOAP利用编译器技术提供了一组透明化的SOAP API,并将与开发无关的SOAP实现细节相关的内容对用户隐藏起来。
gSoap生成C++文件
gSoap开发包的下载地址 http://sourceforge.net/projects/gsoap2 戳这里下载
准备工作:
- E(其他盘符亦可)盘下新建gsoap文件夹,内有soapcpp2.exe、stlvector.h、wsdl2h.exe、soap12.h四个文件。
- 由Web开发部门提供Wsdl描述性url。如果Web端提供的Url是http://192.168.99.201:8003/webapi/art/WhatYouWantServiceTest.asmx,注意要在asmx后缀上?wsdl
- 进入cmd;
输入E:
输入cd gsoap
输入wsdl2h.exe -o RobotArtWS.h http://ws.robotart.cn:8080/WhatYouWant/Authorization?wsdl
输入soapcpp2.exe -j WhatYouWant.h
附操作截图:
有关服务器切换问题
gSoap生成的C++文件中soapWhatYouWantPublicServiceSoapProxy.h中类WhatYouWantPublicServiceSoapProxy中负责初始化一些soap参数。
- 指定namespace
WhatYouWantPublicServiceSoapProxy::WhatYouWantPublicServiceSoapProxy()
{ this->soap = soap_new();
this->soap_own = true;
/*这里是默认namespace*/
m_webUrl = "http://robotart.com/";
WhatYouWantPublicServiceSoapProxy_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
}
WhatYouWantPublicServiceSoapProxy::WhatYouWantPublicServiceSoapProxy(std::string chns1)
{ this->soap = soap_new();
this->soap_own = true;
/*指定新的namespace*/
m_webUrl = chns1;
WhatYouWantPublicServiceSoapProxy_init(SOAP_IO_DEFAULT, SOAP_IO_DEFAULT);
}
void WhatYouWantPublicServiceSoapProxy::WhatYouWantPublicServiceSoapProxy_init(soap_mode imode, soap_mode omode)
{ soap_imode(this->soap, imode);
soap_omode(this->soap, omode);
soap_endpoint = NULL;
static const struct Namespace namespaces[] =
{
{"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://schemas.xmlsoap.org/soap/envelope/", NULL},
{"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://schemas.xmlsoap.org/soap/encoding/", NULL},
{"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL},
{"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL},
{"ns1", m_webUrl.c_str(), NULL, NULL},/*重点在这一句*/
{NULL, NULL, NULL, NULL}
};
soap_set_namespaces(this->soap, namespaces);
}
- 切换Web Service链接
int CWhatYouWantWebService::Login_USCORESSO(std::string &i_strLoginUSO, std::string &o_strLoginUSOResponse)
{
WS_CHECK_ONLINE_LIC();
InitWebServiceProxy();
_ns1__Login_USCORESSO reqLoginUSO;
_ns1__Login_USCORESSOResponse reqLoginUSOResponse;
/*m_sWsUrl,Web Service链接,例如http://api.prepro.WhatYouWant.com:8003/webapi/art/WhatYouWantPublicService.asmx*/
char *cConnectUrl = NULL;
cConnectUrl = const_cast<char*>(m_sWsUrl.data());
/*m_sWsNamespace,命名空间,例如http://WhatYouWant.com/*/
std::string strTemp = m_sWsNamespace + "Login_SSO";
char *cAvtion = const_cast<char*>(strTemp.data());
std::string strBase64Input = apiBase64EnInput(i_strLoginUSO);
reqLoginUSO.input = &strBase64Input;
int iResult = 0;
if (strcmp(cConnectUrl,"")==0)
{
iResult = m_WebService->Login_USCORESSO(NULL, NULL, &reqLoginUSO, reqLoginUSOResponse);
}
else
{
iResult = m_WebService->Login_USCORESSO(cConnectUrl, cAvtion, &reqLoginUSO, reqLoginUSOResponse);
}
if (iResult!=SOAP_OK)
{
return iResult;
}
std::string strResXml = *reqLoginUSOResponse.Login_USCORESSOResult;
std::string strResponse = apiBase64DeOutput(strResXml);
o_strLoginUSOResponse = strResponse;
return iResult;
}
- 超时设置
soap->connect_timeout = nConnectTimeout; //1 sec
soap->recv_timeout = nConnectTimeout * 3; //3 sec
soap->send_timeout = nConnectTimeout * 3; //3 sec
soap->accept_timeout = nConnectTimeout * 3; //3 sec
- 代理设置
soap->proxy_host = m_strHost.c_str();
soap->proxy_port = m_nPort;
soap->proxy_userid = m_strUSerID.c_str();
soap->proxy_passwd = m_strUserPwd.c_str();
参考链接:
https://blog.csdn.net/zhuzhihai1988/article/details/8131370