initial load of upstream version 1.06.32
[xmlrpc-c] / examples / xmlrpc_asynch_client.c
1 /* A simple asynchronous XML-RPC client written in C, as an example of
2    Xmlrpc-c asynchronous RPC facilities.  This is the same as the 
3    simpler synchronous client xmlprc_sample_add_client.c, except that
4    it adds 3 different pairs of numbers with the summation RPCs going on
5    simultaneously.
6
7    Use this with xmlrpc_sample_add_server.  Note that that server
8    intentionally takes extra time to add 1 to anything, so you can see
9    our 5+1 RPC finish after our 5+0 and 5+2 RPCs.
10 */
11
12 #include <stdlib.h>
13 #include <stdio.h>
14
15 #include <xmlrpc-c/base.h>
16 #include <xmlrpc-c/client.h>
17
18 #include "config.h"  /* information about this build environment */
19
20 #define NAME "Xmlrpc-c Asynchronous Test Client"
21 #define VERSION "1.0"
22
23 static void 
24 die_if_fault_occurred (xmlrpc_env * const envP) {
25     if (envP->fault_occurred) {
26         fprintf(stderr, "Something failed. %s (XML-RPC fault code %d)\n",
27                 envP->fault_string, envP->fault_code);
28         exit(1);
29     }
30 }
31
32
33
34 static void 
35 handle_sample_add_response(const char *   const server_url,
36                            const char *   const method_name,
37                            xmlrpc_value * const param_array,
38                            void *         const user_data ATTR_UNUSED,
39                            xmlrpc_env *   const faultP,
40                            xmlrpc_value * const resultP) {
41
42     xmlrpc_env env;
43     xmlrpc_int addend, adder;
44     
45     /* Initialize our error environment variable */
46     xmlrpc_env_init(&env);
47
48     /* Our first four arguments provide helpful context.  Let's grab the
49        addends from our parameter array. 
50     */
51     xmlrpc_decompose_value(&env, param_array, "(ii)", &addend, &adder);
52     die_if_fault_occurred(&env);
53
54     printf("RPC with method '%s' at URL '%s' to add %d and %d "
55            "has completed\n", method_name, server_url, addend, adder);
56     
57     if (faultP->fault_occurred)
58         printf("The RPC failed.  %s", faultP->fault_string);
59     else {
60         xmlrpc_int sum;
61
62         xmlrpc_read_int(&env, resultP, &sum);
63         die_if_fault_occurred(&env);
64
65         printf("The sum is  %d\n", sum);
66     }
67 }
68
69
70
71 int 
72 main(int           const argc, 
73      const char ** const argv ATTR_UNUSED) {
74
75     char * const serverUrl = "http://localhost:8080/RPC2";
76     char * const methodName = "sample.add";
77
78     xmlrpc_env env;
79     xmlrpc_client * clientP;
80     xmlrpc_int adder;
81
82     if (argc-1 > 0) {
83         fprintf(stderr, "This program has no arguments\n");
84         exit(1);
85     }
86
87     /* Initialize our error environment variable */
88     xmlrpc_env_init(&env);
89
90     /* Required before any use of Xmlrpc-c client library: */
91     xmlrpc_client_setup_global_const(&env);
92     die_if_fault_occurred(&env);
93
94     xmlrpc_client_create(&env, XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION, NULL, 0,
95                          &clientP);
96     die_if_fault_occurred(&env);
97
98     for (adder = 0; adder < 3; ++adder) {
99         printf("Making XMLRPC call to server url '%s' method '%s' "
100                "to request the sum "
101                "of 5 and %d...\n", serverUrl, methodName, adder);
102
103         /* request the remote procedure call */
104         xmlrpc_client_start_rpcf(&env, clientP, serverUrl, methodName,
105                                   handle_sample_add_response, NULL,
106                                   "(ii)", (xmlrpc_int32) 5, adder);
107         die_if_fault_occurred(&env);
108     }
109     
110     printf("RPCs all requested.  Waiting for & handling responses...\n");
111
112     /* Wait for all RPCs to be done.  With some transports, this is also
113        what causes them to go.
114     */
115     xmlrpc_client_event_loop_finish(clientP);
116
117     printf("All RPCs finished.\n");
118
119     xmlrpc_client_destroy(clientP);
120
121     return 0;
122 }