准备:
1.安装gSOAP库
2.参考网友资料生成web服务
一(通过端口访问web服务)
1)将安装好的gSOAP目录下的 stdsoap2.c 、stdsoap2.cpp、 stdsoap2.h、soapcpp2、wsdl2h文件拷到服务器目录下(地址自定义)
2)定义头文件(Standalone.h)
<span style="font-size:18px;">//gsoap ns service name: add Simple StandaloneAdd service
//gsoap ns service style: rpc
//gsoap ns service enconding: encoded
//gsoap ns service namespace: http://10.75.58.107/StandaloneAdd.wsdl
//gsoap ns service location: http://10.75.58.107:18888
//gsoap ns schema namesapce: urn:add
int ns__add(double a, double b, double *result);
</span>
头文件主要定义了服务的接口,注释部分不能缺少,这是定义即将生成的wsdl文件相关的属性(包括命名空间,服务所在位置,服务传送的方式等)
3)执行./soapcpp2 -c Standalone.h 生成与web服务相关的文件(命名空间,wsdl文件等,-c生成c文件)
<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<definitions name="add"
targetNamespace="http://10.75.58.107/StandaloneAdd.wsdl"
xmlns:tns="http://10.75.58.107/StandaloneAdd.wsdl"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://10.75.58.107/StandaloneAdd.wsdl"
xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:HTTP="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/"
xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace="http://10.75.58.107/StandaloneAdd.wsdl"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="http://10.75.58.107/StandaloneAdd.wsdl"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<!-- operation request element -->
<element name="a" type="xsd:double"/>
<!-- operation request element -->
<element name="b" type="xsd:double"/>
<!-- operation response element -->
<element name="result" type="xsd:double"/>
</schema>
</types>
<message name="addRequest">
<part name="a" element="ns:a"/><!-- ns__add::a -->
<part name="b" element="ns:b"/><!-- ns__add::b -->
</message>
<message name="addResponse">
<part name="result" element="ns:result"/><!-- ns__add::result -->
</message>
<portType name="addPortType">
<operation name="add">
<documentation>Service definition of function ns__add</documentation>
<input message="tns:addRequest"/>
<output message="tns:addResponse"/>
</operation>
</portType>
<binding name="add" type="tns:addPortType">
<SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="add">
<SOAP:operation style="rpc" soapAction=""/>
<input>
<SOAP:body use="literal" namespace="http://10.75.58.107/StandaloneAdd.wsdl"/>
</input>
<output>
<SOAP:body use="literal" namespace="http://10.75.58.107/StandaloneAdd.wsdl"/>
</output>
</operation>
</binding>
<service name="add">
<documentation>Simple StandaloneAdd service</documentation>
<port name="add" binding="tns:add">
<SOAP:address location="http://10.75.58.107:18888"/>
</port>
</service>
</definitions>
</span>
4)定义服务端文件(StandaloneAdd.c 实现头文件中的接口,并借助gSOAP 库函数处理特定的SOAP数据结构)
<span style="font-size:18px;">#include "soapH.h"
#include "add.nsmap"
int http_get(struct soap*soap)
{
FILE*fd = NULL;
fd = fopen("add.wsdl", "rb"); //open WSDL file to copy
if (!fd)
{
return 404; //return HTTP not found error
}
soap->http_content = "text/xml"; //HTTP header with text /xml content
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; //cannot send, but little we can do about that
}
}
fclose(fd);
soap_end_send(soap);
return SOAP_OK;
}
int main()
{
struct soap soap;
int master, slave;
soap_init(&soap);
soap.fget = http_get;
master = soap_bind(&soap, "10.75.58.107", 18888, 100);
if(master < 0)
soap_print_fault(&soap, stderr);
else
{
//sprintf(stderr, "Socket connection successful:master socket = %d\n", master);
printf("Socket connection successful\n");
while(1)
{
slave = soap_accept(&soap);
if(slave < 0)
{
soap_print_fault(&soap, stderr);
break;
}
//sprintf(stderr, "accepted connection from IP=%d.%d.%d.%d socket=%d",(soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, slave);
if(soap_serve(&soap) != SOAP_OK)
soap_print_fault(&soap, stderr);
fprintf(stderr, "request served\n");
soap_destroy(&soap);
soap_end(&soap);
}
}
soap_done(&soap);
}
int ns__add(struct soap *soap, double a, double b, double *result)
{
*result = a + b;
return SOAP_OK;
}
</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">#include "soapH.h"
#include "add.nsmap"
const char server[] = "http://10.75.58.107:18888";
int main(int argc, char **argv)
{
struct soap soap;
double a, b, result;
soap_init1(&soap, SOAP_XML_INDENT);
a = strtod(argv[2], NULL);
b = strtod(argv[3], NULL);
soap_call_ns__add(&soap, server, "", a, b, &result);
if(soap.error)
{
soap_print_fault(&soap, stderr);
exit(1);
}
else
printf("result = %g\n", result);
soap_destroy(&soap);
soap_end(&soap);
soap_done(&soap);
return 0;
}
</span>
6)编译服务端和客户端
gcc -o StandaloneAdd StandaloneAdd.c stdsoap2.c soapC.c soapServer.c
gcc -o ClientTest ClientTest.c stdsoap2.c soapC.c soapClient.c
7)开启服务
./StandaloneAdd
8)客户端 连接webservice(本地远程皆可)
./ClientTest add 5 6
9)定义php客户端
<span style="font-size:18px;"><?php
try{
$soap = new SoapClient("http://10.75.58.107:18888/?wsdl");
var_dump($soap);
var_dump($soap->__getFunctions());
echo $soap->add(1,5);
}catch(SoapFault $e){
echo $e->getMessage();
}catch(Exception $e){
echo $e->getMessage();
}
?>
</span>
(二)通过cgi访问web服务
定义头文件
<span style="font-size:18px;">// File: currentTime.h
//gsoap ns service name: currentTime
//gsoap ns service namespace: urn:currentTime
//gsoap ns service location: http://10.75.58.73/currentTime.cgi
int ns__currentTime(time_t& response);
</span>
<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<definitions name="currentTime"
targetNamespace="urn:currentTime"
xmlns:tns="urn:currentTime"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="urn:currentTime"
xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:HTTP="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/"
xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace="urn:currentTime"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="urn:currentTime"
xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<!-- operation request element -->
<element name="currentTime">
<complexType>
<sequence>
</sequence>
</complexType>
</element>
<!-- operation response element -->
<element name="currentTimeResponse">
<complexType>
<sequence>
<element name="response" type="xsd:dateTime" minOccurs="1" maxOccurs="1"/><!-- ns__currentTime::response -->
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="currentTimeRequest">
<part name="Body" element="ns:currentTime"/><!-- ns__currentTime::ns__currentTime -->
</message>
<message name="currentTimeResponse">
<part name="Body" element="ns:currentTimeResponse"/>
</message>
<portType name="currentTimePortType">
<operation name="currentTime">
<documentation>Service definition of function ns__currentTime</documentation>
<input message="tns:currentTimeRequest"/>
<output message="tns:currentTimeResponse"/>
</operation>
</portType>
<binding name="currentTime" type="tns:currentTimePortType">
<SOAP:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="currentTime">
<SOAP:operation soapAction=""/>
<input>
<SOAP:body parts="Body" use="literal"/>
</input>
<output>
<SOAP:body parts="Body" use="literal"/>
</output>
</operation>
</binding>
<service name="currentTime">
<documentation>gSOAP 2.8.17r generated service definition</documentation>
<port name="currentTime" binding="tns:currentTime">
<SOAP:address location="http://10.75.58.73/cgi-bin/currentTime.cgi"/>
</port>
</service>
</definitions>
</span>
// File: currentTime.cpp
#include "soapH.h" // include the generated declarations
#include "currentTime.nsmap" // include the XML namespace mappings
int main()
{
// create soap context and serve one CGI-based request:
return soap_serve(soap_new());
// soap_destroy(&soap); // dealloc C++ data
// soap_end(&soap);
// return 0;
}
int ns__currentTime(struct soap *soap, time_t& response)
{
response = time(0);
return SOAP_OK;
}
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
try{
$soap = new SoapClient("http://10.75.58.73/cgi/currentTime.wsdl");
// $soap = new SoapClient("http://10.75.58.190/webservice/add.wsdl");
var_dump($soap);
var_dump($soap->__getFunctions());
//currentTime(currentTime $Body)
var_dump($soap->currentTime());
//echo $soap->add(11,15);
}catch(SoapFault $e){
echo $e->getMessage();
}catch(Exception $e){
echo $e->getMessage();
}
?>