Being able to create both a client and server so easily in C# is nice, but the use of C# is restricted to the Windows environment. For other environments, I will use the gSOAP Toolkit. It produces, given a WSDL file, all the code necessary to connect to the web service.
To install gSOAP version 2.7.13, first download gsoap_2.7.13.tar.gz to a temporary directory, e.g. /tmp/gsoap
Then, do the following, replacing /tmp/gsoap with your directory:
$ cd /tmp/gsoap $ gzip -dc < gsoap_2.7.13.tar.gz | tar -xf - $ cd gsoap_2.7.13
$ ./configure --prefix=/usr $ make
# make install
Upon installation, gsoap produces the following files: (assuming --prefix=/usr)
First off, if we want to make a client for the HelloService, we will need to get a hold of HelloService.wsdl. For a WCF web service, we can get this by typing in the URL of the service with a "?wsdl" suffix. For example, http://localhost:8000/HelloService?wsdl. From this WSDL file, gSOAP can generate all of the necessary code for communicating with the server.
gSOAP, once installed, provides us with two tools: wsdl2h and soapcpp2. We will use both of them.
$ cd /tmp/client $ ls -l HelloService.wsdl
$ wsdl2h -c -s HelloService.wsdl $ ls -l HelloService.h HelloService.wsdl
$ soapcpp2 -c -C -L HelloService.h $ ls -l BasicHttpBinding_USCOREHelloService.GetHello.req.xml BasicHttpBinding_USCOREHelloService.GetHello.res.xml BasicHttpBinding_USCOREHelloService.nsmap HelloService.h HelloService.wsdl soapC.c soapClient.c soapH.h soapStub.h
#include "BasicHttpBinding_USCOREHelloService.nsmap" #include <stdio.h> const char* GetHello(struct soap *soap) { struct _ns3__GetHello msgInput; struct _ns3__GetHelloResponse msgOutput; if(soap_call___ns1__GetHello(soap,0,0,&msgInput,&msgOutput)!=SOAP_OK) { soap_print_fault(soap,stderr); return 0; } else { return msgOutput.GetHelloResult; } } int main() { const char *str; struct soap *soap = soap_new(); str = GetHello(soap); printf("The server said : %s\n", str); return 0; }
CC=cc
LDFLAGS=`pkg-config gsoap --libs`
HelloClient5 : HelloClient5.o soapC.o soapClient.o
${CC} -o HelloClient5 HelloClient5.o soapC.o soapClient.o ${LDFLAGS}
HelloClient5.o : HelloClient5.c
${CC} -c HelloClient5.c
soapC.o : soapC.c
${CC} -c soapC.c -ansi
soapClient.o : soapClient.c
${CC} -c soapClient.c -ansi
clean :
rm -f test.o soapC.o soapClient.o
update :
wsdl2h -c -s HelloService.wsdl
soapcpp2 -c -C -L HelloService.h
$ make $ ./HelloClient5 The server said : hello
Here's an inside look of the conversation between the HelloClient and HelloService.
POST /HelloService HTTP/1.1
Host: door.mvpsi.com:8000
User-Agent: gSOAP/2.7
Content-Type: text/xml; charset=utf-8
Content-Length: 504
Connection: close
SOAPAction: "http://petio.org/2009/07/22/HelloService/HelloService/GetHello"
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
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:ser="http://schemas.microsoft.com/2003/10/Serialization/"
xmlns:tns="http://tempuri.org/"
xmlns:m="http://petio.org/2009/07/22/HelloService">
<SOAP-ENV:Body>
<m:GetHello></m:GetHello>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Content-Length: 218
Content-Type: text/xml; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 04 Aug 2009 22:14:23 GMT
Connection: close
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetHelloResponse xmlns="http://petio.org/2009/07/22/HelloService">
<GetHelloResult>hello</GetHelloResult>
</GetHelloResponse>
</s:Body>
</s:Envelope>
(The above XML was formatted for this example)