SOAP current time client & server example ========================================= Overview -------- This example implements a simple SOAP/XML API client and server in C++ to obtain the current time. The Web service specified is a tiny one-liner. The client and server programs are tiny too. A more interesting one-liner example service is our [gSOAP Docker container example](../docker/index.html) that does not require a Web server installed as it runs an image of a stand-alone service within a container. [![To top](../../images/go-up.png) To top](#) Web services specification example ---------------------------------- The XML Web service is specified in the [`gmt.h`](gmt.h) file for the gSOAP soapcpp2 tool to process. This [`gmt.h`](gmt.h) specification defines one operation in just one line of code to return the current time in GMT: t__gmt(time_t*); [![To top](../../images/go-up.png) To top](#) Implementing the client application ----------------------------------- The client application [`gmtclient.cpp`](gmtclient.cpp) is run at the command line and prints the current time: #include "soapH.h" #include "gmt.nsmap" int main() { time_t t; struct soap *soap = soap_new(); soap_call_t__gmt(soap, "http://localhost:8080", "", &t); printf("The current time is %s\n", ctime(&t)); soap_destroy(soap); soap_end(soap); soap_free(soap); return 0; } See the [tutorials](https://www.genivia.com/tutorials.html) on how to use HTTP proxies and HTTPS. [![To top](../../images/go-up.png) To top](#) Build steps for the client application -------------------------------------- Generate the service and data binding interface for the client side with: [command] soapcpp2 -r -CL gmt.h where option `-r` generates a report, and option `-CL` generates the client side only without (the unused) lib files. This generates several files, including: * [`soapStub.h`](soapStub.h) a copy of the specification in plain C/C++ header file syntax without annotations. * [`soapH.h`](soapH.h) declares XML serializers. * [`soapC.cpp`](soapC.cpp) implements XML serializers. * [`soapClient.cpp`](soapClient.cpp) implements the client-side XML services API. * [`gmt.nsmap`](gmt.nsmap) XML namespace binding table to #include * [`soapReadme.md`](soapReadme.html) service and data binding interface details. To build the example client application we also need `stdsoap2.h` and `stdsoap2.cpp`: [command] c++ -o gmtclient gmtclient.cpp stdsoap2.c soapC.cpp soapClient.cpp [![To top](../../images/go-up.png) To top](#) Implementing a CGI server application ------------------------------------- The CGI server application [`gmtserver.cpp`](gmtserver.cpp) implements the service operations and accepts requests on stdin using `soap_serve(soap)`: #include "soapH.h" #include "gmt.nsmap" int main() { return soap_serve(soap_new()); } int t__gmt(struct soap *soap, time_t *t) { *t = time(0); return SOAP_OK; } Install the CGI application in the cgi-bin folder of your Web server. To implement stand-alone services running as a Web server without requiring a third-party Web server such as Apache, see the [calc++ example](../calc/index.html) for an example. See also our [tutorials](https://www.genivia.com/tutorials.html) for details on deploying services with Apache or IIS and how to increase the robustness of services. [![To top](../../images/go-up.png) To top](#) Implementing a stand-alone server application --------------------------------------------- The stand-alone local server application [`gmtserver_local.cpp`](gmtserver_local.cpp) implements the service operations and accepts requests on port 8080. #include "soapH.h" #include "gmt.nsmap" int main() { struct soap *soap = soap_new(); SOAP_SOCKET m = soap_bind(soap, NULL, 8080, 1); if (soap_valid_socket(m)) == SOAP_OK { fprintf(stderr, "Socket connection successful: master socket = %d\n", m); while (true) { SOAP_SOCKET s = soap_accept(soap); fprintf(stderr, "Socket connection successful: socket = %d\n", s); if (soap_valid_socket(s) != SOAP_OK) break; soap_serve(soap); soap_destroy(soap); soap_end(soap); } } soap_print_fault(soap, stderr); soap_free(soap); exit(1); } int t__gmt(struct soap *soap, time_t *t) { *t = time(0); return SOAP_OK; } [![To top](../../images/go-up.png) To top](#) Build steps for the server application -------------------------------------- Generate the service and data binding interface for the server side with: [command] soapcpp2 -r -SL gmt.h where option `-r` generates a report, and option `-SL` generates the server side only without (the unused) lib files. This generates several files, including: * [`soapStub.h`](soapStub.h) a copy of the specification in plain C/C++ header file syntax without annotations. * [`soapH.h`](soapH.h) declares XML serializers. * [`soapC.cpp`](soapC.cpp) implements XML serializers. * [`soapServer.cpp`](soapServer.cpp) implements the server-side XML services API. * [`gmt.nsmap`](gmt.nsmap) XML namespace binding table to #include * [`soapReadme.md`](soapReadme.html) service and data binding interface details. To build the example server application we also need `stdsoap2.h` and `stdsoap2.cpp`: [command] c++ -o gmtserver gmtserver.cpp stdsoap2.cpp soapC.cpp soapServer.cpp c++ -o gmtserver_local gmtserver_local.cpp stdsoap2.cpp soapC.cpp soapServer.cpp [![To top](../../images/go-up.png) To top](#) Running the example ------------------- [command] ./gmtserver_local & ./gmtclient The current time is Sun Jun 4 15:43:22 2017 [![To top](../../images/go-up.png) To top](#) Readme report ------------- See the auto-generated [soapReadme](soapReadme.html) for this example. [![To top](../../images/go-up.png) To top](#)