C++-style eventing client and event handler server. Events are one-way SOAP messages using HTTP keep-alive for persistent connections. This example illustrates one-way message exchange patterns (MEP) between a client and server, each with C and C++ implementations. samples/event: event.c C-based client handler.c C-based multithreaded server (uses Pthreads) samples/event++: event.cpp C++-based client handler.cpp C++-based server (uses Pthreads) For HTTP communications events are not truly one-way, since HTTP Accept or OK responses are expected to be returned to the client. Thus, this is a form of synchronous communication with rendezvous. The code also supports true one-way messaging, by setting the global flag synchronous = 0. Note that all send operations may or may not block. Receive operations always block. All four files are built with the web service definitions given in the gSOAP header file event.h. The event.h file is processed with soapcpp2 as follows: Compilation in C: soapcpp2 -c event.h cc -o event event.c stdsoap2.c soapC.c soapClient.c cc -o handler handler.c stdsoap2.c soapC.c soapServer.c Compilation in C++: soapcpp2 -i event.h cc -o event++ event.cpp stdsoap2.cpp soapC.cpp soapEventProxy.cpp cc -o handler++ handler.cpp stdsoap2.cpp soapC.cpp soapEventService.cpp soap EventProxy.cpp The C client-side uses: Initialization of the runtime engine: soap_init(struct soap*) soap_init2(struct soap*, soap_mode input_modes, soap_mode output_modes) Sending an event to the handler, this function is generated by soapcpp2: soap_send_ns__handle(struct soap*, const char *endpoint, const char *action, enum ns__event event) Note: pass endpoint=NULL and action=NULL for defaults To accept an HTTP Accept or OK message (ack): soap_recv_empty_response(struct soap*) Receiving an event from the handler, this function is generated by soapcpp2: soap_recv_ns__handle(struct soap*, struct ns__handle*) Set and reset HTTP keep-alive connections (optional): soap_set_omode(soap, SOAP_IO_KEEPALIVE) soap_clr_omode(soap, SOAP_IO_KEEPALIVE) Close the socket (to end a keep-alive session) soap_closesocket(struct soap*) Print communication errors: soap_print_fault(struct soap*, FILE*) Allocate data, which stays alive until deallocated by soap_end() soap_malloc(struct soap*, size_t len) Delete deserialized data: soap_end(struct soap*) Finalize and detach the runtime engine: soap_done(struct soap*) The multi-threaded C server-side uses: Initialization of the runtime engine: soap_init(struct soap*) soap_init2(struct soap*, soap_mode input_modes, soap_mode output_modes) Binding the port: soap_bind(struct soap*, const char *host, int port, int backlog) Accepting a request: soap_accept(struct soap*); Invoking the service dispatcher, this function is generated by soapcpp2: soap_serve(struct soap*) Print communication errors: soap_print_fault(struct soap*, FILE*) Allocate data, which stays alive until deallocated by soap_end() soap_malloc(struct soap*, size_t len) Delete deserialized data: soap_end(struct soap*) Send back sender-related fault: soap_sender_fault(struct soap*, const char *string, const char *detailXML) Send back receiver-related fault: soap_receiver_fault(struct soap*, const char *string, const char *detailXML) Make a copy of the current runtime engine: soap_copy(struct soap*) Finalize and detach the runtime engine: soap_done(struct soap*) Finalize, detach, and delete the runtime engine: soap_free(struct soap*) Service operation is not auto-generated (user-defined): ns__handle(struct soap*, enum ns__event *event); Sending an event to the client, this function is generated by soapcpp2: soap_send_ns__handle(struct soap*, const char *endpoint, const char *action, enum ns__event event) where we use endpoint = "http://" to send message over current socket The C++ client-side uses a proxy generated with soapcpp2 -i: class EventProxy Constructor EventProxy(soap_mode input_output_modes) The default endpoint can be changed: const char *EventProxxy::endpoint Invoke a call of xyz: EventProxy::xyz(double a, double b, double *result) Print communication errors: EventProxy::soap_stream_fault(std::ostream&) Error code (see list of error codes in documentation and stdsoap2.h): EventProxy::error Allocate data, deallocated by soap_end() or EventService destructor soap_malloc(EventService*, size_t len) Get new instance of class X, deallocated by soap_destroy() or EventService destructor soap_new_X(EventService*, -1) Get array of new instances of class X, deallocated by soap_destroy() or EventService destructor soap_new_X(EventService*, arraylen) Delete deserialized C++ class instances (also part of EventService destructor): soap_destroy(EventService*) Delete deserialized data (also part of EventService destructor): soap_end(EventService*) The C++ server-side uses the server and proxy classes generated with soapcpp2 option -i. A proxy instance is needed for the one-way send operation. Create a serivce copy for new thread EventService::copy() Bind port EventService::bind(const char *host, int port, int backlog) Accept and set socket EventService::accept() Serve requests over current socket EventService::serve() Print communication errors: EventService::soap_stream_fault(std::ostream&) Error code (see list of error codes in documentation and stdsoap2.h): EventService::error Send back sender-related fault: EventService::soap_senderfault(const char *string, const char *detailXML) Send back sender-related fault with subcode (SOAP 1.2): EventService::soap_senderfault(const char *subcodeQName, const char *string, const char *detailXML) Send back receiver-related fault: EventService::soap_receiverfault(const char *string, const char *detailXML) Send back receiver-related fault with subcode (SOAP 1.2): EventService::soap_receiverfault(const char *subcodeQName, const char *string, const char *detailXML) Service operations are user-defined (not auto-generated): EventService::handle(enum ns__event *event) Allocate data, deallocated by soap_end() or EventService destructor soap_malloc(EventService*, size_t len) Get new instance of class X, deallocated by soap_destroy() or EventService destructor soap_new_X(EventService*, -1) Get array of new instances of class X, deallocated by soap_destroy() or EventService destructor soap_new_X(EventService*, arraylen) Delete deserialized C++ class instances (also part of EventService destructor): soap_destroy(EventService*) Delete deserialized data (also part of EventService destructor): soap_end(EventService*) Note: all soap_xyz(struct soap*, ...) gSOAP API functions are also available to the EventProxy and EventService classes by inheritance of the struct soap runtime engine state object.