The typographical conventions used by this document are:
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119.
To comply with WS-I Basic Profile 1.0a, gSOAP 2.5 and higher adopts SOAP document/literal by default. There is no need for concern, because the WSDL parser wsdl2h automatically takes care of the differences when you provide a WSDL document, because SOAP RPC encoding, literal, and document style are supported. A new soapcpp2 compiler option was added -e for backward compatibility with gSOAP 2.4 and earlier to adopt SOAP RPC encoding by default in case you want to develop a service that uses SOAP encoding. You can also use the gSOAP soapcpp2 compiler directives to specify SOAP encoding for individual operarations, when desired.
You should read this section only if you are upgrading from gSOAP 2.1 to 2.2 and later. Run-time options and flags have been changed to enable separate recv/send settings for transport, content encodings, and mappings. The flags are divided into four classes: transport (IO), content encoding (ENC), XML marshalling (XML), and C/C++ data mapping (C). The old-style flags soap_disable_X and soap_enable_X, where X is a particular feature, are deprecated. See Section 9.12 for more details.
You should read this section only if you are upgrading from gSOAP 1.X to 2.X. gSOAP versions 2.0 and later have been rewritten based on versions 1.X. gSOAP 2.0 and later is thread-safe, while 1.X is not. All files in the gSOAP 2.X distribution are renamed to avoid confusion with gSOAP version 1.X files:
|
Changing the version 1.X application codes to accommodate gSOAP 2.X does not require a significant amount of recoding. The change to gSOAP 2.X affects all functions defined in stdsoap2.c[pp] (the gSOAP runtime context API) and the functions in the sources generated by the gSOAP soapcpp2 compiler (the gSOAP RPC+marshalling API). Therefore, clients and services developed with gSOAP 1.X need to be modified to accommodate a change in the calling convention used in 2.X: In 2.X, all gSOAP functions (including the service operation proxy routines) take an additional parameter which is an instance of the gSOAP runtime context that includes file descriptors, tables, buffers, and flags. This additional parameter is always the first parameter of any gSOAP function. The gSOAP runtime context is stored in a struct soap type. A struct was chosen to support application development in C without the need for a separate gSOAP implementation. An object-oriented approach with a class for the gSOAP runtime context would have prohibited the implementation of pure C applications. Before a client can invoke service operations or before a service can accept requests, a runtime context needs to be allocated and initialized. Three new functions are added to gSOAP 2.X:
|
A context can be reused as many times as necessary and does not need to be reinitialized in doing so. A dynamically allocated context is deallocated with soap_free. A new context is only required for each new thread to guarantee exclusive access to a new runtime context by each thread. For example, the following code stack-allocates the runtime context which is used for multiple service operation calls:
int main() { struct soap soap; ... soap_init(&soap); // initialize runtime context ... soap_call_ns__method1(&soap, ...); // make a remote call ... soap_call_ns__method2(&soap, ...); // make another remote call ... soap_destroy(&soap); // remove deserialized class instances (C++ only) soap_end(&soap); // clean up and remove deserialized data soap_done(&soap); // detach context (last use and no longer in scope) ... } |
The runtime context can also be heap allocated:
int main() { struct soap *soap; ... soap = soap_new(); // allocate and initialize runtime context if (!soap) // couldn't allocate: stop ... soap_call_ns__method1(soap, ...); // make a remote call ... soap_call_ns__method2(soap, ...); // make another remote call ... soap_destroy(soap); // remove deserialized class instances (C++ only) soap_end(soap); // clean up and remove deserialized data soap_free(soap); // detach and free runtime context } |
A service needs to allocate and initialize an context before calling soap_serve:
int main() { struct soap soap; soap_init(&soap); soap_serve(&soap); } |
Or alternatively:
int main() { soap_serve(soap_new()); } |
The soap_serve dispatcher handles one request or multiple requests when HTTP keep-alive is enabled (with the SOAP_IO_KEEPALIVE flag see Section 19.11). A service can use multi-threading to handle requests while running some other code that invokes service operations:
int main() { struct soap soap1, soap2; pthread_t tid; ... soap_init(&soap1); if (soap_bind(&soap1, host, port, backlog) < 0) exit(1); if (soap_accept(&soap1) < 0) exit(1); pthread_create(&tid, NULL, (void*(*)(void*))soap_serve, (void*)&soap1); ... soap_init(&soap2); soap_call_ns__method(&soap2, ...); // make a remote call ... soap_end(&soap2); ... pthread_join(tid, NULL); // wait for thread to terminate soap_end(&soap1); // release its data } |
In the example above, two runtime contexts are required. In comparison, gSOAP 1.X statically allocates the runtime context, which prohibits multi-threading (only one thread can invoke service operations and/or accept requests due to the single runtime context). Section 7.2.4 presents a multi-threaded stand-alone Web Service that handles multiple SOAP requests by spawning a thread for each request.
gSOAP interoperability has been verified with the following SOAP implementations and toolkits:
Apache 2.2
Apache Axis
ASP.NET
Cape Connect
Delphi
easySOAP++
eSOAP
Frontier
GLUE
Iona XMLBus
kSOAP
MS SOAP
Phalanx
SIM
SOAP::Lite
SOAP4R
Spray
SQLData
WCF
White Mesa
xSOAP
ZSI
4S4C