Let's see the server/client generation for a simple service: HelloService.
<?xml version="1.0" encoding="UTF-8"?> <definitions name="HelloService" targetNamespace="http://www.emilmont.net/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.emilmont.net/wsdl/HelloService.wsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <message name="SayHelloRequest"> <part name="firstName" type="xsd:string"/> </message> <message name="SayHelloResponse"> <part name="greeting" type="xsd:string"/> </message> <portType name="Hello_PortType"> <operation name="sayHello"> <input message="tns:SayHelloRequest"/> <output message="tns:SayHelloResponse"/> </operation> </portType> <binding name="Hello_Binding" type="tns:Hello_PortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHello"> <soap:operation soapAction="sayHello"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:examples:helloservice" use="encoded"/> </output> </operation> </binding> <service name="Hello_Service"> <documentation>WSDL File for HelloService</documentation> <port binding="tns:Hello_Binding" name="Hello_Port"> <soap:address location="http://localhost:8888"/> </port> </service> </definitions>
The gSOAP release distribution package provides two compiler tools to develop your applications:
The 'wsdl2h' parser converts WSDL into gSOAP header file specifications of Web services. This specification gives a C/C++ transparent view of the server's functionality. The header file is processed by 'soapcpp2' to generate the source code stubs and skeletons to invoke the service or build a new service based on the WSDL.
wsdl2h -c HelloService.wsdl soapcpp2 -c HelloService.h
Server.c
#include "soapH.h" #include "Hello_USCOREBinding.nsmap" int main(int argc, char* argv[]) { int m, s; struct soap soap; soap_init(&soap); m = soap_bind(&soap, NULL, 8888, 100); if (m < 0) { soap_print_fault(&soap, stderr); exit(-1); } fprintf(stderr, "Socket connection successful\n"); while (1) { s = soap_accept(&soap); if (s < 0) { soap_print_fault(&soap, stderr); exit(-1); } soap_serve(&soap); soap_end(&soap); } return 0; } int ns1__sayHello(struct soap *soap, char* firstName, char* *greeting) { printf("ns1__sayHello(%s)\n", firstName); *greeting = (char*)soap_malloc(soap, 25); sprintf(*greeting, "Hello %s", firstName); return SOAP_OK; }
Client.c
#include "soapH.h" #include "Hello_USCOREBinding.nsmap" int main(int argc, char **argv) { struct soap soap; char* greeting; soap_init(&soap); if (soap_call_ns1__sayHello(&soap, "http://localhost:8888", NULL, "world", &greeting) == SOAP_OK) { printf("%s\n", greeting); } else { soap_print_fault(&soap, stderr); } return 0; }
A possible Makefile can be:
# C Compiler settings CC=gcc CC_FLAGS=-DLINUX -g -O2 -Wall # Header files needed by the compiler CC_INCLUDES=-I. -pthread # Libraries needed by the linker LD_LIBS=-pthread \ -L/usr/lib \ -Wl,-rpath,/usr/lib \ -lgsoap # Project Files MODULES_SERVER=./Server.o \ ./soapServer.o \ ./soapC.o MODULES_CLIENT=./Client.o \ ./soapClient.o \ ./soapC.o all: server client clean: rm -f server client $(MODULES_SERVER) $(MODULES_CLIENT) server: $(MODULES_SERVER) $(CC) $(CC_INCLUDES) $(CC_FLAGS) -o $@ $(MODULES_SERVER) $(LD_LIBS) client: $(MODULES_CLIENT) $(CC) $(CC_INCLUDES) $(CC_FLAGS) -o $@ $(MODULES_CLIENT) $(LD_LIBS) %.o: %.c $(CC) $(CC_INCLUDES) $(CC_FLAGS) -c -o $*.o $<