C++: windows使用gsoap开发webservice程序(单线程)---服务端

来源:互联网 发布:java服务器用linux 编辑:程序博客网 时间:2024/06/08 02:02

  最近工作中需要将公司c++实现的人脸识别服务做成web服务,小伙伴推荐用gSoap,就找他来做网络代理,在生成通讯代码是-i选项让我很好奇。工作完成后,就随手试试,发现开发的代码省了好多,忍不住记录下来。

 

  维基百科:gsoap是用于soap/XML web服务和通用xml数据绑定的c/c++软件开发工具包。

      gSoap工具为任何类型的c/c++数据的xml序列化生成零拷贝开销的高效源代码。其中,Soap是传输协议,Xml是数据传输的格式。

 

  通俗来讲:gSoap 工具可依据待提供服务接口的c/c++头文件(有固定格式)生成对应的wsdl文件以及负责数据打包,传输以及解包的c/c++底层代码。此时,开发人员可将自己的精力投入上层业务逻辑,甚至不需要了解soap协议。

 

  下载什么的就不说了。

  发布服务的流程:编写接口文件 -> wsdl以及底层通讯代码->将前文生成的代码嵌入到自己的人脸比对服务程序中。此处随便写个简单的测试接口。

 

  服务器端:

1.编写接口文件:如lxx_test.h

//gsoap ns service name: lxx_test

//gsoap ns service namespace: http://localhost:8090/lxx_test.wsdl

//gsoap ns service location: http://localhost:8090

//gsoap ns service executable: lxx_test.cgi

//gsoap ns service encoding: encoded

//gsoap ns schema namespace: urn:lxx_test

int ns__test1(std::string input1,std::string &result);

 

  此头文件提供了一个test1的接口,ns是命名空间(还没理清为什么这种格式),下划线是“ns__”两条,此文件格式很重要。注意://gsoap ns schema namespace:~urn:lxx_test,中的“~”相当于是空格,如果没有,会影响生成的wsdl文件的完整性(亲测)。

 Localhost:可改为具体的ip.

       2. 生成wsdl文件以及底层通讯代码

  生成这些文件需要gsoap提供的工具:soapcpp2.exewsdl2h.exe(开发客户端时使用)。由于需要传参,我将这些步骤写到脚本文件里:

新建txt文件,并更名为make_wsdl.bat

编辑内容:

cd /d ./

soapcpp2.exe -S -i lxx_test.h

ping 127.0.0.1 -n 10 >nul

解释:

1) cd /d ./    ===》进入当前目录

2) soapcpp2.exe -S -i lxx_test.h   ===Soapcpp2.exe的参数-S仅生成服务器端代码,-i生成c++代理(c++程序员使用方便,此处先使用代理类)。Soapcpp2.exe -h可查询全部选项。

3) ping 127.0.0.1 -n >nul   ===》打印信息一闪而过,此句仅为了实现时延,好看清打印信息。

 

双击运行脚本之后,生成文件:


  (下文参考http://www.mamicode.com/info-detail-1853229.html)

        soapStub.h// soap的存根文件,定义了接口文件里里对应的远程调用模型

       soapC.cpp,soapH.h//soap的序列和反序列代码,它已经包含了soapStub.h,

       Lxx_test.nsmap//命名空间定义

       soaplxx_testService.cpp,soaplxx_testService.h//服务器端的c++代码封装。


  3.c++工程,进行编程。

  开发程序时需要gsoap包中提供的stdsoap2.hstdsoap2.cpp这两个文件(提供一些基本的定义和声明)。

Main.cpp

#include <iostream>

 

#include "web_module\soapH.h"

#include "web_module\soaplxx_testService.h"

#include "web_module\lxx_test.nsmap"

//必须实现,否则不能通过http访问获取。

int http_get(struct soap *soap)

{

FILE *fd = fopen("web_module\\lxx_test.wsdl","rb");

if(!fd)

{

return 404;

}

soap->http_content="text/xml";

soap_response(soap,SOAP_FILE);

for(;;)

{

size_t r=fread(soap->tmpbuf,1,sizeof(soap->tmpbuf),fd);

if(!r)

{

break;

}

if(soap_send_raw(soap,soap->tmpbuf,r))

{

break;

}

}

fclose(fd);

soap_end_send(soap);

return SOAP_OK;

}

 

int main()

{

lxx_testService ws;//lxx_testService就是生成的服务端代理类

ws.fget = http_get;

while(1)

{

if(ws.run(8090))

{

ws.soap_stream_fault(std::cerr);

}

}

return 0;

}

//test1是生成的一个纯虚函数,需要我们自己实现

int lxx_testService::test1(const std::string& input1, std::string &result)

{

result.append("lxx is always a beautiful girl!\n");

return SOAP_OK;

}

 

4. 测试:

打开SoapUI工具:新建soap工程,并输入正确的wsdl地址。

  点击绿色三角按钮,发送请求。返回结果如下图:


   成功返回结果。




阅读全文
0 0
原创粉丝点击