libxmlrpc_client++

This chapter describes the functions in the libxmlrpc_client++ function library, which is part of XML-RPC For C/C++ (Xmlrpc-c). Also see General Library Information - C++.

You must know something about XML-RPC (the protocol) to understand this chapter. You don't have to know the details of the protocol, since Xmlrpc-c is meant to spare you from learning that, but you do have to know the kinds of things that make up an XML-RPC transaction.

Everything you need to know about XML-RPC is on the XML-RPC web site.

The libxmlrpc_client++ library provides C++ classes for use in a program that is an XML-RPC client. These classes take care of all the protocol related things so the calling program can be very simple.

There are 4 separate levels of client facilities in Xmlrpc-c. Each successive level requires more code, skill, and thought on your part, but gives you more options. The libxmlrpc_client++ library gives you the first two, which are described below as Simple Client and Complex Client. The next level down would be to use the libxmlrpc++ library to generate call XML and parse response XML, but use your own code to transport the XML via HTTP. The lowest level is actually not to use Xmlrpc-c at all. Build and parse XML with your own code and transport it as well.

The Complex Client facilities are actually very general. You can use them to make a client that isn't exacty XML-RPC. For example, it might not use HTTP and might not use XML. Or you could substitute your own code for almost any piece of the Xmlrpc-c suite. For example, you might pull canned XML out of somewhere and use libxmlrpc_client++ facilities to transport it easily. It all depends on which classes you choose to use.

When using libxmlrpc_client++, you must also use the libxmlrpc++ library. It contains additional facilities that an XML-RPC client needs but are general to XML-RPC and not specific to XML-RPC clients. Besides, the libxmlrpc_client++ library routines depend on it.

Chapter Contents

Interface Header File

The <xmlrpc-c/client++.hpp> header file declares the interface to the general parts of libxmlrpc_client++. Other header files declare special facilities; the sections that describe these identify those header files.

You'll have to figure out where on your system these header files live and how to make your compiler look there for them. Or use xmlrpc-c-config.

Linking The Library

The classic Unix name for the file containing the libxmlrpc_client++ library is libxmlrpc_client++.a or libxmlrpc_client++.so. The classic linker option to cause the library to be linked into your program is -l xmlrpc_client++. These are hints; you'll have to modify this according to conventions of your particular platform. You'll also have to figure out where the library resides and how to make your linker look there for it. Or use xmlrpc-c-config.

The following libraries are prerequisites of libxmlrpc_client++, so you'll need to link them in too:

And remember that some static linkers care about the order in which you specify the libraries, with the prerequisite libraries having to come after the prerequiring library. xmlrpc-c-config is a good way to make sure you link all the prerequisites in the right order.

Example

A complete example of an XML-RPC client program that uses libxmlrpc_client++ is here.

An example of the main part of the same program using the more flexible Complex Client facilities is here.

Testing, Experimenting

You can use the same techniques as you would with client code based on the C client library.

Simple Client

This section describes the highest level, simplest, and least flexible means that libxmlrpc_client++ provides for writing an XML-RPC client program.

See Introductory Examples for a complete example of a simple XML-RPC client in C++.

Class clientSimple

An object of this class is an XML-RPC client with limited function, but easy to use. You use this client to perform RPCs, i.e. communicate with XML-RPC servers.

Contrary to what you would think, you may not have more than one object of this class in a program. The code is not re-entrant -- it uses global variables.

Here are some of the limitations of the simple client as compared to lower level Xmlrpc-c facilities:

Interface Header File

This class is declared in header file <xmlrpc-c/client_simple.hpp>.

Constructors

There is only one constructor: the no-argument constructor.

Remember you can't have more than one object of this class in a program. Nothing will stop you from constructing two of them, but they will interfere with each other as you use them.

call Method

The call method performs an XML-RPC RPC. It returns when the RPC is complete.

The method throws a girerr:error if it is not able to perform the RPC. In that case, it may or may not have started the RPC and if it has started it, it may or may not complete later. But as far as the xmlrpc_c::clientSimple object is concerned, the RPC is history.

There are three forms of arguments for the call method:

RPC Has No Parameters

To perform an RPC that has no parameters, just use this:


    void
    call(std::string       serverUrl,
         std::string       methodName,
         xmlrpc_c::value * resultP);

Example:


    xmlrpc_c::value bathTempV;
    myClient.call("http://bathtub_control.acme.com/RPC2",
                  "get_temperature",
                  &bathTempV
    double const bathTemp = xmlrpc_c::value_double(bathTempV);
    cout << "Bath temperature is " << bathTemp << endl;

RPC Has Predictable Simple Parameter Structure

If the RPC has parameters, and you know at coding time what form they take, and none of them is complex (i.e. an array or structure), use this:


    void
    call(std::string       serverUrl,
         std::string       methodName,
         std::string       format,
         xmlrpc_c::value * resultP,
         ...);

Example:


    xmlrpc_c::value result;
    myClient.call("http://localhost:8080/RPC2", "sample.add",
                  "ii", &result, 5, 7);
    int const sum = xmlrpc_c::value_int(result);              
    cout << "Result of RPC (sum of 5 and 7): " << sum << endl;

The serverUrl, methodName, and resultP arguments are self-explanatory.

The format argument is like a printf format string and specifies the form of the parameters. The variable arguments (...) are the arguments specified by the format string.

The format string is the same as the C interface's format string, but there is an important difference in how you use it. With the C interface, the format string specifies a single array value, and the elements of that array are the RPC parameters. In the C++ methods, the format string simply specifies the parameters, in sequence. So to specify the two integer parameters for the "sample.add" method in the above example in the C interface, you would use the format string "(ii)", whereas to specify those two parameters in the C++ interface, you use "ii" (and "(ii)" would mean something else).

The reason for the difference is that the C interface is stupid. It makes it look like the RPC actually has one array parameter. In fact, in the C interface, unlike the C++ interface, there are not types specifically to represent XML-RPC entities such as values and parameter lists. Unlike the C++ xmlrpc_c::value type, the C xmlrpc_value type is a general purpose data structure.

Note that the A, S, and V format specifiers are unlikely to be useful to you, because they correspond to data types that you don't (normally) use in a C++ program. In a program that uses the C versions of the Xmlrpc-c libraries, an A specifier, for example, says the parameter is an XML-RPC array and you are supplying its value as a pointer to a data structure of type xmlrpc_value, which is the C equivalent of C++'s xmlrpc_c::value. Furthermore, there is no C++ equivalent to A, S, and V. E.g. you can't supply an array parameter with an xmlrpc_c::value_array variable, using the format string version of call.

If you want to use your xmlrpc_c::value_array data structure as an XML-RPC RPC parameter, use instead the version of call that takes an xmlrpc_c::paramList argument. (Your xmlrpc_c::value_array will be an argument to the add method of the xmlrpc_c::paramList).

RPC Has Varying or Complex Parameters

Sometimes you don't know at coding time what kind of parameters your RPC will need. Maybe the RPC has a variable parameter list like a C++ method. Maybe the user tells you the method and parameters and you don't know anything about the method. In this case, you can't use the printf-style call.

Also, if one of your parameters is an array or structure, you can't use the printf-style call.

Instead, use an xmlrpc_c::paramList object, which you build using logic as complex as you need.

Prototype:


    void
    call(std::string         serverUrl,
         std::string         methodName,
         xmlrpc_c::paramList paramList,
         xmlrpc_c::value *   resultP);

Example:


    xmlrpc_c::value result;
    xmlrpc_c::paramList sampleAddParms;
    sampleAddParms.add(xmlrpc_c::value_int(5));
    sampleAddParms.add(xmlrpc_c::value_int(7));
    myClient.call("http://localhost:8080/RPC2", "sample.add",
                  sampleAddParms, &result);
    int const sum = xmlrpc_c::value_int(result);              

    cout << "Result of RPC (sum of 5 and 7): " << sum << endl;

Complex Client

Example


    xmlrpc_c::clientXmlTransport_curl myTransport;
    xmlrpc_c::client_xml myClient(&myTransport);

    string const methodName("sample.add");

    xmlrpc_c::paramList sampleAddParms;
    sampleAddParms.add(xmlrpc_c::value_int(5));
    sampleAddParms.add(xmlrpc_c::value_int(7));

    xmlrpc_c::rpcPtr myRpcP(methodName, sampleAddParms);

    string const serverUrl("http://localhost:8080/RPC2");

    xmlrpc_c::carriageParm_curl0 myCarriageParm(serverUrl);

    myRpcP->call(&myClient, &myCarriageParm);

    assert(myRpcP->isFinished());

    int const sum((xmlrpc_c::value_int(myRpcP->getResult())));
        // Assume the method returned an integer; throws error if not

    cout << "Result of RPC (sum of 5 and 7): " << sum << endl;

Following is a more compact and more natural C++ way to generate the parameter list object sampleAddParms in the above example. Drawbacks of this method are that you can't represent every possible XML-RPC parameter list this way and it may be harder for a newcomer to Xmlrpc-c to decipher.


    xmlrpc_c::paramList sampleAddParms
    sampleAddParms.addc(5).addc(7);

Overview

Because of the great flexibility these facilities give you in kinds of RPCs and ways of performing them, you need several kinds of objects to perform an RPC.

You fundamentally need an RPC object, a client object, and a carriage parameter object to perform an RPC. In regular XML-RPC, you also need an XML transport object.

There is an object for each RPC. The RPC's method name and parameters are properties of the RPC. The state of execution is another. The identity of the server and the protocols used to communicate with the server are not. An RPC is oblivious to the fact that XML and HTTP are used in performing it. Its only connection to XML-RPC is the kinds of parameters and outcomes it can have. An RPC is an object of Class xmlrpc_c::rpc.

There is an object for a client. The protocols for performing an RPC are properties of the client. If you're using true XML-RPC, the fact that XML and HTTP are used is a property of the client. Clients that don't use those (i.e. non-XML-RPC clients) are also possible. A client object is an object of Class xmlrpc_c::client.

A client that uses XML (such as any true XML-RPC client) has an XML transport object associated with it. An XML transport object knows the protocols for getting XML to and from a server. For example, one kind of XML transport object uses HTTP via a Curl library. An XML transport object is an object of Class xmlrpc_c::clientXmlTransport.

A carriage parameter object describes how to transport a particular RPC. Its precise meaning depends on the kind of client. For an XML client, its meaning depends on the kind of XML transport. For example, with a true XML-RPC client that uses the Curl HTTP library, the carriage parameter tells the URL of the server, basic authentication userid and password if necessary, and the network interface to use. A carriage parameter object is an object of Class xmlrpc_c::carriageParm.

Asynchronous Client

The simplest way to use libxmlrpc_client++ is synchronously, where your program makes a call that performs a whole RPC, then moves on. I.e. performance of RPCs is synchronous with the execution of your program. To use the library synchronously, you use the call method of Class xmlrpc_c::rpc.

But synchronous operation is limiting because you can't have multiple RPCs in progress at the same time and your (single-thread) program can't do other things while an RPC executes. So you can alternatively use libxmlrpc_client++'s asynchronous client facilities to create multiple threads of execution (within a single operating system thread).

The heart of the asynchronous client facility is the start method of the xmlrpc_c::rpc class. It's like call, except that it returns immediately, even if the RPC is still underway. Your program can then go on to start additional RPCs or do whatever else it wants. Eventually, it calls the client's finishAsync method to cause all outstanding RPCs started by that client to complete.

To be even more asynchronous, you can specify a timeout for finishAsync or interrupt it with a signal and do some other stuff before eventually calling it again.

But: the asynchronous client facility is not so asynchronous that you can just start an RPC and forget about it. When you start an RPC, you must eventually finish it and recognize that it has completed. Until then, it is using resources and may not even progress. RPCs are inherently synchronous, in that there's a response that tells the client that the server has completed its work. If you want a communication style where you just throw a message out and walk away and it arrives when it arrives, you should consider something other than an RPC protocol. A simple UDP packet sometimes works. JSON-RPC, despite its name, has facilities for that too.

If you're just looking for a way to avoid waiting indefinitely for a slow RPC, the asynchronous RPC facility is not for you. You probably want the RPC interruption facility.

Examples

Here is an example of code that uses the asynchronous facilities.


    myRpcP->start(&myClient, &myCarriageParm);
    myClient.finishAsync(xmlrpc_c::timeout());
    assert(myRpcP->isFinished();

The code above is actually synchronous -- it's the equivalent of the folllowing; its only purpose is to help you understand how the facilities work.


    myRpcP->call(&myClient, &myCarriageParm);
    assert(myRpcP->isFinished();

Note that the default constructor of xmlrpc_c::timeout() constructs an infinite timeout, so in the example, finishAsync runs until the RPC is finished, no matter how long that takes.

Here is a more useful example: two RPCs execute simultaneously.


    myRpcP->start(&myClient, &myCarriageParm);
    myOtherRpcP->start(&myClient, &myCarriageParm);
    myClient.finishAsync(xmlrpc_c::timeout());
    assert(myRpcP->isFinished();
    assert(myOtherRpcP->isFinished();

For a complete example of a program that performs RPCs asynchronously, see asynch_client in the examples/cpp/ directory of the Xmlrpc-c source tree (starting with Release 1.12 (September 2007)).

Basic How-to

As mentioned above, start starts an RPC.

You can tell when the RPC has finished with the isFinished method. Also, when the RPC finishes, its notifyComplete method gets called. You can make your own RPC class, derived from xmlrpc_c::rpc, that has a notifyComplete method that notifies you somehow.

While the RPC is running, the client object maintains a reference to it. So you can destroy all your pointers to it right after start returns, and the RPC will cease to exist after it finishes.

Most clients are not capable of performing an RPC entirely asynchronously to the client's method callers. That means if you start an RPC by calling start and then call isFinished repeatedly forever, you will find that the RPC never finishes. The client is able asynchronously to do parts of the RPC that don't require any instructions to execute, such as wait for the server to respond, and parts that require only operating system execution, such as receive the response, but it doesn't have a thread of its own to do such things as interpret the response and set the "finished" flag.

So after calling start, you must eventually call the client's finishAsync method. If it returns before the RPC is complete (because you specified a timeout or interrupted it with a signal), you must eventually call it again. You must do this even if you no longer care if the RPC finishes, because until it finishes, it will consume resources.

The exact nature of the asynchronicity depends highly on the client XML transport involved. start may in actuality wait for the RPC to finish. Or it might not even really start it, and finishAsync might do all the work. See the sections on the transport classes (e.g. Class xmlrpc_c::clientXmlTransport_curl) for details.

Failed RPC, Exception

You can approach exceptions at varying levels of complexity. You can keep your code simple and just assume the server and network and all of the infrastructure are working normally and have no code that (other than high level generic exception handlers) that considers the various things that might go wrong. Or you can look at the results of RPCs in detail and respond specially to individual kinds of exceptions.

The simple method is what you see in examples above. After doing an RPC, you simply assume that it completed normally and call the RPC's getResult method to get the result. (Furthermore, you can assume the result is of the type you expect and convert the xmlrpc_c::value accordingly). If you're wrong and, say, the server failed the RPC, getResult throws an error. Somebody higher up can deal with that; your immediate code doesn't worry about it.

For the more complex method, an xmlrpc_c::rpc object has methods you can use to query the disposition of the RPC.

isSuccessful tells you whether the RPC succeeded (i.e. the server returned an XML-RPC result response). If it did, you can then call getResult. If it didn't (i.e. the server returned an XML-RPC fault response), you can call getFault to get the contents of the fault response.

Another kind of error is where the RPC doesn't execute at all. For example, the network is down or the server you're going for doesn't exist. When that happens, whether the RPC is successful or not is meaningless, as are its result or fault information, and all the above methods throw an error. There isn't any way to query whether the RPC failed to even execute or to distinguish programmatically among the myriad reasons that it might. However, the girerr::error thrown contains an English description of the exact problem.

Class xmlrpc_c::rpc

An object of this class is an individual RPC. The main reason there is an object for this is so that you can have an asynchronous program, with multiple RPCs in progress at the same time. But even if you write a synchronous program and use the synchronous Xmlrpc-c facilities, you need these objects.

One of the properties of an RPC object is the execution status of the RPC. Has it been started yet? Has it finished? Has an error prevented the RPC from executing?

Other properties of an RPC include the identity of the method, the parameters, and the outcome.

Class xmlrpc_c::rpc is derived from girmem::autoObject. Its associated pointer class is xmlrpc_c::rpcPtr. You normally access it via such a pointer. In fact, you can even create it implicitly when you create a pointer. Before Xmlprpc-c 1.05 (March 2006), the usual auto-object pointer construction paradigm (rpcPtr myRpcP(new rpc(...)) doesn't even work -- you must create the rpc implicitly.

Most programmers see an RPC from the top, which means from a program that wants to perform an RPC. But some of the members form a view of the RPC from the bottom -- from the code that actually makes the RPC happen. This bilateral view exists because of the fact that RPCs can be asynchronous. It is equivalent to the situation in a device driver, where a top interface starts I/O and a bottom interface handles I/O interrupts.

The bottom-facing methods are clearly marked below and are of concern to you only if you are developing an xmlrpc_c::client subclass.

Constructors

Prototype:


    rpc(std::string         methodName,
        xmlrpc_c::paramList paramList);

This constructs a new xmlrpc_c::rpc object.

You should normally construct a xmlrpc_c::rpc object via the conventional auto-object paradigm rpcPtr myrpcP(new rpc(...)). That lets the library take care of destroying the object when you are done with it and makes it harder for you to destroy it prematurely.

You must use a rpcPtr if you plan to use asynchronous RPC execution facility (i.e. the xmlrpc_c::rpc::start method) because otherwise Xmlrpc-c code will destroy the RPC as soon as it finishes, since it will appear to be unreferenced. But there is no way you can write your code to guarantee it won't still reference the RPC after it finishes, because the Xmlrpc-c calls you make to conduct the asynchronous execution reference the RPC.

The methodName argument is self-explanatory.

The paramList argument is the parameter list of the RPC as an xmlrpc_c::paramList object.

The new RPC is in the "not started" state. Nothing will happen with the RPC until you call its call or start method.

You can alternatively construct an rpc object implicitly by constructing an rpcPtr pointer. But the preferred way starting with Xmlrpc-c 1.05 (March 2006) is to use the conventional auto-object paradigm rpcPtr myrpcP(new rpc(...)).

call Method

This method performs the RPC. It returns when the RPC is finished or the RPC object has found it impossible and given up. The method fails if the RPC is already in progress.

The method does not return the outcome of the RPC. You can get that with additional methods such as isSuccessful and getResult. Example:


    xmlrpc_c::rpcPtr myRpcP(new rpc("sample.add", sampleAddParms));
    myRpcP->call(&myClient, &myCarriageParm);
    int const sum((xmlrpc_c::value_int(myRpcP->getResult())));
    cout << "Result of RPC (sum of 5 and 7): " << sum << endl;

There are two forms of this method.

call by client and carriage parameter

Prototype:


    void
    call(xmlrpc_c::client       * clientP,
         xmlrpc_c::carriageParm * carriageParmP);

This performs the RPC using client *clientP and carriage parameter *carriageParmP. Those two objects tell how to deliver the RPC call to the server and get the response back.

See class client and class carriageParm.

In an ordinary XML-RPC client, clientP points to an xmlrpc_c::client_xml object and carriageParmP points to a xmlrpc_c::carriageParm_http object.

call by connection

Prototype:


    void
    call(xmlrpc_c::connection connection);

This is the same as above, but using an xmlrpc_c::connection object to deliver the call and receive the response.

start method

This method starts an RPC, but does not wait for it to finish. The RPC may finish before or after the method returns.

The arguments are the same as for call.

Use this to perform RPCs asynchronously. See Asynchronous Client.

isFinished Method

Prototype:


    bool isFinished() const;

This method returns true if and only if the RPC is finished. If the RPC object is unable to execute the RPC and has given up, that counts as finished.

Note that to use this properly, you have to call the client's run method between calls to isFinished. See the start method for an explanation.

isSuccessful Method

Prototype:


    bool isSuccessful() const;

This method returns true if and only if the RPC has succeeded, in an XML-RPC sense. I.e. it has executed completely and did not return a fault.

getResult Method

Prototype:


    xmlrpc_c::value getResult() const;

This method returns the result of the successful RPC. If the RPC has not succeeded, this throws a girerr::error. You can use isSuccessful to determine whether you can successfully call getResult.

getFault Method

This method returns the description of the fault with which the RPC failed. If the RPC has not failed, this throws a girerr::error.

You can use isFinished and isSuccessful to partially determine whether you can successfully call getFault. But note that those two methods won't distinguish between an RPC that failed and an RPC that the client wasn't able to execute at all. There are 3 possible results of starting an RPC: 1) The RPC executes and succeeds in an XML-RPC sense (i.e. returns an XML-RPC result); 2) The RPC executes, but fails in an XML-RPC sense (i.e. returns an XML-RPC fault); 3) The RPC doesn't execute (for example, because the network is down). If the RPC didn't execute, getFault() throws an error, and there is no other way to determine that the RPC didn't execute.

Prototype:


    xmlrpc_c::fault getFault() const;

notifyComplete Method

This is a bottom-facing method, as described above. Ordinary client programs don't call this, but they often override it.

This method is supposed to notify someone somehow that the RPC has finished. The xmlrpc_c:rpc class' notifyComplete does nothing; you override it in a derived class that you write specifically for your program. But if your program does not need any notification, you needn't override it.

Prototype:


    void notifyComplete();

Note that the implementation of notifyComplete() normally uses other methods such as this->getResult to ascertain the outcome of the RPC.

finish Method

This is a bottom-facing method, as described above. Ordinary client programs don't use this. This method declares that the RPC is finished and succeeded. The method's argument is the RPC's result as an xmlrpc_c::value object.

finishFail Method

This is like finish, but declares that the RPC failed. It was fully executed, but failed in an XML-RPC sense. The method's argument is an xmlrpc_c::fault object describing the failure.

finishErr Method

This is like finish, but declares that the client was unable to execute the RPC cleanly. The call may or may not have been made and if it was, the response may or may not have been received. The RPC may have finished successfully, failed, or neither. The method's argument is a girerr::error object describing the error.

Class xmlrpc_c::rpcPtr

An object of this class is a pointer to an object of class xmlrpc_c::rpc. The class is derived from girmem::autoObjectPtr.

Constructors

You will normally just use the constructors of the base class, for consistency with Xmlrpc-c's various other auto-object classes.

Example:


    rpcPtr const myrpcP(new rpc(std::string         methodName,
                                xmlrpc_c::paramList paramList));

But for backward compatibility with releases based on an earlier design philosophy, you can also use a constructor that implicitly creates the rpc object to which the rpcPtr points, without your code ever seeing the rpc directly.

Example:


    rpcPtr const myrpcP(std::string         methodName,
                        xmlrpc_c::paramList paramList);

Class xmlrpc_c::client

An object of this class represents a client, which is something that communicates with servers.

This is an abstract base class. You can't create a generic object of this class, but rather create an object of a derived class that communicates with servers in a certain way. The normal derived class (the only one provided by Xmlrpc-c) is xmlrpc_c::client_xml.

This class is derived from girmem::autoObject. Its associated pointer class is xmlrpc_c::clientPtr. But this is true only in Xmlrpc-c 1.05 (March 2006) and later.

finishAsync Method

This method causes the client to synchronize with all outstanding RPCs. It's part of the asynchronous client facility -- if you use the start method of an xmlrpc_c::rpc object, you need this too.

The method causes all outstanding RPCs to finish and waits for them. For some clients, the thread of this method is what finishes the RPCs, so no RPC can finish until you call this.

Prototype:


    void finishAsync(xmlrpc_c::timeout timeout);

The function waits no longer than timeout milliseconds for RPCs to complete. You can call finishAsync again later to finish any RPCs that are left unfinished because of the timeout.

call Method

This method performs an RPC. An ordinary client program does not use this method, because it performs RPCs via the methods of an xmlrpc_c::rpc object.

start Method

This method starts an RPC. An ordinary client program does not use this method, because it performs RPCs via the methods of an xmlrpc_c::rpc object.

setInterrupt Method

This method declares an interrupt flag for a client. Henceforth, you can interrupt various client operations by setting that flag to a nonzero value. The interrupt flag works the same way as the one for the C client library.

Prototype:


    void setInterrupt(int * interruptFlag);

To clear the interrupt flag, specify NULL for interruptP.

If you call this while the client is in the middle of something, results are undefined. Normally, you call this only as part of setting up a client, shortly after you create it.

Not all clients are interruptible. On some of the ones that aren't, this method throws a girerr:error; on others it simply has no effect.

In particular, only a client of class xmlrpc_c::client_xml is interruptible; setInterrupt of a client of any other class throws an error. Among clients of class xmlrpc_c::client_xml, only those using a xmlrpc_c::clientXmlTransport_curl transport are interruptible. setInterrupt of any other client has no effect.

This function was new in Xmlrpc-c 1.13 (December 2007). Before that, there is no way to interrupt a client operation (but there is for a C client).

Class xmlrpc_c::clientPtr

An object of this class is a pointer to an object of class xmlrpc_c::client. This class is derived from girmem::autoObjectPtr.

Class xmlrpc_c::client_xml

An object of this class is an xmlrpc_c::client object that performs an RPC using XML-RPC XML. The object is not necessarily an XML-RPC client, though, as it does not necessarily use HTTP to transport that XML. You supply a separate XML transport object that transports the XML in a way of your choosing.

Constructors

Prototypes:


    client_xml(xmlrpc_c::clientXmlTransport * transportP);


    client_xml(xmlrpc_c::clientXmlTransport * transportP,
               xmlrpc_dialect                 dialect);


    client_xml(xmlrpc_c::clientXmlTransportPtr transportP);


    client_xml(xmlrpc_c::clientXmlTransportPtr transportP);
               xmlrpc_dialect                  dialect);

transportP points to an object that transports the client's XML (calls and responses). See class xmlrpc_c::clientXmlTransport. In true XML-RPC, this is an object that knows how to communicate via HTTP, e.g. xmlrpc_c::clientXmlTransport_http.

dialect selects the dialect that the client will use when it generates the XML for a method call parameter.

Note that this has no effect on the dialect the client is able to interpret in responses from a server. The client understands all the dialects.

If you use a constructor without dialect, the dialect is i8.

If you use a constructor that takes a C++ pointer (xmlrpc_c::clientXmlTransport *) to identify the transport, you must ensure that the transport continues to exist as long as the client does. You don't have to worry about that when you use the clientXmlTransportPtr -- the transport knows when it is being used by the client and won't disappear before then.

The clientXmlTransportPtr constructor was new in Xmlrpc-c 1.05 (March 2006).

The constructors with dialect where new in Xmlrpc-c 1.11 (June 2007).

Class xmlrpc_c::clientXmlTransport

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client.

A normal client program does not access an xmlrpc_c::clientXmlTransport object except to create it and give it to an xmlrpc_c::client_xml object.

This is an abstract base class. You can't create a generic object of this class, but rather create an object of a derived class that transports XML in a certain way. The normal derived class (the only one provided by Xmlrpc-c) is xmlrpc_c::clientXmlTransport_http.

An object of Class xmlrpc_c::clientXmlTransport processes transactions. A transaction is delivery of a call and reception of its associated response. When you use the asynchronous interface to the transport, you have to supply an xmlrpc_c::xmlTransaction object to represent each transaction.

This class is derived from girmem::autoObject. Its associated pointer type is xmlrpc_c::clientXmlTransportPtr. This is true starting with Xmlrpc-c 1.04 (November 2005).

call Method

This method transports a call to the server and receives and returns the response.

Prototype:


    void
    call(xmlrpc_c::carriageParm * carriageParmP,
         std::string              callXml,
         std::string *            responseXmlP);

start Method

This method transports a call to the server and associates it with a transaction. It does not wait for or receive the response.


    void
    start(xmlrpc_c::carriageParm *    carriageParmP,
          std::string                 callXml,
          xmlrpc_c::xmlTransactionPtr xmlTranP);

xmlTranP is a pointer to an xmlTransaction object that represents the transaction (call/response). This is the object that the xmlrpc_c::clientXmlTransport object notifies (by calling its finish or finishErr method) when it has received the response. See class xmlTransaction.

Having successfully called start() (It didn't throw an error), you must later call finishAsync(). You must keep calling it until the transaction xmlTranP completes. If you fail to do this, you will probably consume resources at the least. Furthermore, the RPC typically won't even get transported and the transaction will never complete because the transport object relies on your thread to do the work, via your call to finishAsync().

finishAsync Method

This method causes the transport to synchronize with all outstanding transactions. The method causes all outstanding transactions to complete and waits for them. For some transports, the thread of this method is what finishes the transactions, so no transaction can complete until you call this.

Prototype:


    void finishAsync(xmlrpc_c::timeout timeout);

The function waits no longer than timeout milliseconds for transactions to complete. You can call finishAsync again later to finish any transactions that are left uncompleted because of the timeout.

Class xmlrpc_c::clientXmlTransportPtr

An object of this class is a pointer to an object of class xmlrpc_c::clientXmlTransport. The class is derived from girmem::autoObjectPtr.

This class was new in Xmlrpc-c 1.04 (November 2005).

Class xmlrpc_c::clientXmlTransport_http

This is a derived class of xmlrpc_c::clientXmlTransport.

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client, using HTTP.

As with all xmlrpc_c::clientXmlTransport objects, a normal client program does not access an xmlrpc_c::clientXmlTransport_http object except to create it and give it to an xmlrpc_c::client_xml object.

This is an abstract base class. You can't create a generic object of this class, but rather create an object of a derived class that uses HTTP using a certain HTTP library. Xmlrpc-c provides three such classes: xmlrpc_c::clientXmlTransport_curl, xmlrpc_c::clientXmlTransport_libwww, and xmlrpc_c::clientXmlTransport_wininet.

If you don't care which one (and unless you're doing something fancy, there's no reason you should), you can use the class method create to create a transport object of a class of libxmlrpc_client++'s choosing.

Some people build variations of the Xmlrpc-c libraries that don't have all of the transports mentioned above available, or that have extra ones. To find out which ones are available, you can use the availableTypes class method. This is also a good reason to use create, since it always chooses a transport class that is actually available.

create Class Method

This method creates an object of a derived class of Class xmlrpc::clientXmlTransport_http. Which of various derived classes it uses is arbitrary. Use this when you don't care, don't want to decide, or don't know which derived classes are implemented in your version of libxmlrpc_client++.

(The other way to create an object derived from clientXmlTransport_http is to use the constructor of the particular derived class).

Example:


    xmlrpc::clientXmlTransportPtr const transportP(
        xmlrpc::clientXmlTransport_http::create());
    client_xml myClient(transportP);

Prototype:


    static xmlrpc::clientXmlTransportPtr create();

Note that because you don't control what kind of transport you get, you can't ordinarily use any features or parameters that are specific to a particular one. You must use a carriage parameter of class xmlrpc::carriageParm_http0, which has only controls that are common to all HTTP transports.

If you really want to know which kind of object you got, you can use trial dynamic casts to find out.

The create class method was new in Xmlrpc-c 1.05 (March 2006).

availableTypes Class Method

This method returns a list of the names of the available client XML transport classes in the library.

Example:


    using namespace std;
    vector<string> const typeList(
        xmlrpc::clientXmlTransport_http::availableTypes();
    vector<string>::const_iterator i;
    for (i = typeList.begin(); i != typeList.end(); ++i)
        cout << "Available transport class: "
             << *i
             << endl;    

Prototype:


    static std::vector<std::string>
    availableTypes();

The availableTypes class method was new in Xmlrpc-c 1.05 (March 2006).

Class xmlrpc_c::clientXmlTransport_curl

This is a derived class of xmlrpc_c::clientXmlTransport_http.

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client, using HTTP courtesy of the Curl HTTP client library.

As with all xmlrpc_c::clientXmlTransport_http objects, a normal client program does not access an xmlrpc_c::clientXmlTransport_curl object except to create it and give it to an xmlrpc_c::client_xml object.

Constructors

The no-argument constructor works. The more general constructor is as follows. The no-argument constructor does the same thing as the general one with no options specified.

Example (new in Xmlrpc-c 1.04 (November 2005)):


    xmlrpc_c::clientXmlTransport_curl myTransport(
        xmlrpc_c::clientXmlTransport_curl::constrOpt()
        .network_interface("eth0")
        .no_ssl_verifyhost(true)
        );

This rather complex constructor is actually quite easy to use if you follow the example instead of trying to understand how it works. This is a common C++ use paradigm that lets a subroutine have named parameters. See C++ Named Arguments for an explanation.

The option names (i.e. the names of the option setter methods, such as "network_interface") are identical to the parameter names in the Curl transport of the C interface. The option meanings are of course the same.

Before Xmlrpc-c 1.04 (November 2005), the constructor was different as follows. This constructor continues to exist for backward compatibility.


    clientXmlTransport_curl(std::string networkInterface = "",
                            bool        noSslVerifyPeer = false,
                            bool        noSslVerifyHost = false,
                            std::string user_agent = "");

The meanings of the arguments are the same as for the corresponding parameters in the Curl transport of the C interface.

Interference With Other Modules

The Curl library, and the various other libraries it uses, unfortunately use global variables. That means if another part of your program uses one of these libraries for something via a means other than Xmlrpc-c, there can be problems. These global variables are the sort of thing that one would normally never change from defaults, such as the identity of the memory allocator (malloc). Xmlrpc-c does not change these from defaults, but if something else in your program does, there could be unpredictable results.

An essential part of this uneasy peace between Xmlrpc-c and competing users of the Curl library (and actually, between multiple xmlrpc_c::clientXmlTransport_curl objects) is that Xmlrpc-c code never "cleans up" the Curl global variables. I.e. it never calls the Curl library's curl_global_cleanup(). That means there can be a trivial amount of leaked memory. If you want a cleaner program, call curl_global_init() yourself before creating any clientXmlTransport_curl objects, and call curl_global_cleanup() after any such objects have ceased to exist. Note that curl_global_init() is repeatable -- after the first call, subsequent calls have no effect, so it's not a problem if both you and Xmlrpc-c call it.

The facilities Curl uses that have this problem are:

The global settings that the Curl library itself manipulates are:

Concurrency

You may call the methods of a clientXmlTransport_curl object (transport) from multiple threads simultaneously. You may use the same transport for multiple xmlrpc_c::client_xml objects.

A clientXmlTransport_curl object uses pthread locking on Unix systems and Windows locking on Windows. So your environment must provide these facilities whether you want to use multiple threads or not.

You may have multiple clientXmlTransport_curl objects in a process.

When you use the synchronous interface (such as the call method of a xmlrpc_c::rpc object does), a clientXmlTransport_curl object transports RPCs one at a time, in the order requested. So if you have multiple pthreads all doing xmlrpc_c::rpc::calls via the same clientXmlTransport_curl object, you will never have more than one HTTP transaction in progress at a time.

To get multiple RPCs executing concurrently using the synchronous interface, you can use multiple clientXmlTransport_curl objects. Each one has a separate serial stream of HTTP transactions and therefore RPCs.

However, there are some significant differences between transporting two RPCs with the same transport object and transporting them with separate objects:

When you use the asynchronous transport interface (such as the start method of a xmlrpc_c::rpc object does) with multiple operating system threads, you get a rather strange beast, because you have Xmlrpc-c threads inside of operating system threads. It works, but probably has different concurrency characteristics than you want. You'll get something very similar to using the synchronous transport interface with multiple operating system threads.

The Curl transport does one DNS server host name lookup at a time, and the timeout of the transport's and client's finishAsync method are ineffective against long-running name lookups. This is due to a weakness in the Curl library (at least as late as version 7.16.1 -- January 2007).

Class xmlrpc_c::clientXmlTransport_libwww

This is a derived class of xmlrpc_c::clientXmlTransport_http.

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client, using HTTP courtesy of the W3C Libwww HTTP client library.

As with all xmlrpc_c::clientXmlTransport_http objects, a normal client program does not access an xmlrpc_c::clientXmlTransport_libwww object except to create it and give it to an xmlrpc_c::client_xml object.

An object of this class is not thread safe. You must not call a method while another thread is running a method of the same object. The same goes for any client object that uses the object.

You can still have a multithreaded program with this class; you just have to construct multiple transport (and client) objects -- one for each thread. Or do explicit threading using the start method of an xmlrpc_c::rpc object.

Constructors

Prototype:


    clientXmlTransport_libwww(std::string appname = "",
                              std::string appversion = "");

The meanings of the arguments are the same as for the Libwww transport of the C interface.

Class xmlrpc_c::clientXmlTransport_wininet

This is a derived class of xmlrpc_c::clientXmlTransport_http.

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client, using HTTP courtesy of the Wininet HTTP client facility built into Windows.

As with all xmlrpc_c::clientXmlTransport_http objects, a normal client program does not access an xmlrpc_c::clientXmlTransport_wininet object except to create it and give it to an xmlrpc_c::client_xml object.

Constructors

Prototype:


    clientXmlTransport_wininet(bool allowInvalidSslCerts = false);

The meanings of the arguments are the same as for the Wininet transport of the C interface.

Class xmlrpc_c::clientXmlTransport_pstream

This is a derived class of xmlrpc_c::clientXmlTransport.

An object of this class transports XML (arbitrary strings, actually) to and from a server for a client, using a packet stream. As XML-RPC requires HTTP, not a packet stream, when you use this transport, your client is not an XML-RPC client and it will not talk to an XML-RPC server. We call it a packet stream XML-RPC client; think of it as pseudo-XML-RPC. You can use it to talk to a server that uses Xmlrpc-c packet stream XML-RPC server facilities. For more information on this protocol, see that server manual.

As with all xmlrpc_c::clientXmlTransport objects, a normal client program does not access an xmlrpc_c::clientXmlTransport_pstream object except to create it and give it to an xmlrpc_c::client_xml object.

A transport of this class talks to exactly one server. You fix the identity of that server before you construct the object. Furthermore, it uses exactly one connection to that server. You establish that connection before you construct the object.

This class was new in Xmlrpc-c 1.11 (June 2007).

Constructors

Prototype:


    clientXmlTransport_pstream(constrOpt & opt);

This constructor uses the constrOpt paradigm to make specifying options easy and flexible, though technically there is just one C++ parameter.

The option methods are:

fd
(integer) File descriptor of a stream socket that is connected to a packet stream XML-RPC server. (It just has to be connected at the stream socket level, such as one would do with the connect() standard C library function -- no prior packet stream negotiation is implied).

You can control a lot of the behavior of the transport just by your choice of socket parameters (which you make before you pass it to the clientXmlTransport_pstream constructor). However, you are not allowed to access the socket in any way while the object exists.

useBrokenConnEx
(boolean) When a method is unable to perform its normal function (e.g. sending a call to the server) because the TCP connection broke (because the server hung up or the network failed), the method throws an xmlrpc_c::clientXmlTransport_pstream::BrokenConnectionEx object if this option is true. Otherwise, the method just throws a girerr::error like any other error.

Note that the OS may not know the connection is broken when you try to use it, so instead of throwing the object immediately, the method may run for a long time before the OS realizes the connection is broken. It can even run indefinitely. Use the TCP keepalive feature to help the OS determine when the connection is broken.

On a POSIX system, Xmlrpc-c considers a function to have failed because of a broken connection when a system call to communicate with the server fails with one of these errnos:

BrokenConnectionEx has no members.

This option method, and the BrokenConnectionEx class, were new in Xmlrpc-c 1.46 (June 2016).

Class xmlrpc_c::xmlTransaction

An object of this class represents an XML transaction that an xmlrpc_c::clientXmlTransport object performs. You need this class only if you are using an XML transport and using it asynchronously (i.e. transactions can be in progress while your program is doing something else).

A normal XML-RPC client program never sees this class because its objects are internal to the xmlrpc_c::rpc class.

There is an obvious connection between an XML transaction (class xmlrpc_c::xmlTransaction) and an RPC (class xmlrpc_c::rpc). When you're doing XML-RPC, every RPC is associated with exactly one XML transaction. In that case, the object that represents the XML transaction is typically of derived class xmlrpc_c::xmlTransaction_client.

Class xmlrpc_c::xmlTransaction is derived from girmem::autoObject. Its associated pointer class is xmlrpc_c::xmlTransactionPtr.

Constructors

No constructors are available for public use. Instead, construct an xmlrpc_c::xmlTransactionPtr. That will automatically construct a new xmlrpc_c::xmlTransaction to which to point.

finish Method

This method notifies somebody somehow that the XML response has been received. The method's argument is the XML. The generic xmlrpc_c::xmlTransaction version of the method does nothing, but you typically override it in a derived class.

finishErr

This method notifies somebody somehow that the transaction has failed and no response XML will be forthcoming.

The generic xmlrpc_c::xmlTransaction version of the method does nothing, but you typically override it in a derived class.

Class xmlrpc_c::xmlTransactionPtr

An object of this class is a pointer to an object of class xmlrpc_c::xmlTransaction. This class is derived from girmem::autoObjectPtr.

Constructors

The no-argument constructor creates a placeholder pointer. It doesn't point to anything, but you can assign another pointer value to it later. There are no other constructors; typically, you construct an object of a derived class. You might then assign that object's value to a placeholder xmlrpc_c::xmlTransactionPtr object.

class xmlrpc:c::carriageParm

An object of this class tells how to transport an RPC. It describes parameters that may vary from one RPC to the next.

This is an abstract base class. You can't create a generic object of this class, but rather create an object of a derived class that means something for some particular kind of client. For example, an HTTP client might use a carriage parameter that includes a URL, and maybe a userid/password for HTTP basic authentication.

This base class has no members of its own.

Xmlrpc-c provides the following derived classes, all for clients of class xmlrpc_c::client_xml:

The first three are derived from yet another class, xmlrpc_c::carriageParm_http0, which is itself derived from xmlrpc_c::carriageParm. carriageParm_http0 represents parameters common to all HTTP transportation.

Class xmlrpc_c::carriageParm_http0

An object of this class is an xmlrpc_c::carriageParm object that is suitable as the carriage parameter for a xmlrpc_c::client_xml client that uses an XML transport of the class xmlrpc_c::xmlTransport_http.

This class is derived from girmem::autoObject. Its associated pointer class is xmlrpc_c::carriagepparmhttp0Ptr. But this is true only in Xmlrpc-c 1.05 (March 2006) and later.

Constructors

Example:


    xmlrpc_c::carriageParm_http0 const myParm("http://localhost:8080/RPC2");

The argument, obviously, is the server URL mdash it tells to where to make the HTTP connection over which to perform the RPC.

setUser Method

This sets the username and password to be used in identifying and authenticating the client, for those authentication methods that involve usernames and passwords.

This function by itself does not enable any authentication. You must separately call a method such as allowAuthBasic as well.

Prototype:


    void
    setUser(std::string const userid,
            std::string const password);

This function was new in Xmlrpc-c 1.14 (March 2008).

allowAuthBasic Method

Prototype:


    void
    allowAuthBasic();

This sets the carriage parameter to indicate that HTTP basic authentication is allowed with the server.

You must set a username and password with setUser before calling this, or it will fail.

Use disallowAuthBasic to undo this.

This function was new in Xmlrpc-c 1.14 (March 2008).

disallowAuthBasic Method

Prototype:


    void
    disallowAuthBasic();

This sets the carriage parameter to indicate that HTTP basic authentication is not allowed with the server.

This undoes what allowAuthBasic does.

This function was new in Xmlrpc-c 1.14 (March 2008).

allowAuthDigest Method

This is analogous to allowAuthBasic, except for HTTP digest authentication.

disallowAuthDigest Method

This is analogous to disallowAuthDigest, except for HTTP digest authentication.

allowAuthNegotiate Method

This is analogous to allowAuthBasic, except for HTTP GSS-Negotiate authentication.

disallowAuthNegotiate Method

This is analogous to disallowAuthDigest, except for GSS-Negotiate authentication.

allowAuthNtlm Method

This is analogous to allowAuthNtlm, except for HTTP NTLM authentication.

disallowAuthNtlm Method

This is analogous to disallowAuthNtlm, except for HTTP NTLM authentication.

setBasicAuth Method

This method is obsolete. In new code, use allowBasic and setUser instead.

This method is equivalent to the combination of allowBasic and setUser.

Class xmlrpc_c::carriageParm_http0Ptr

An object of this class is a pointer to an object of class xmlrpc_c::carriageparmhttp0. This class is derived from girmem::autoObjectPtr.

Class carriageParm_curl0

An object of this class is an xmlrpc_c::carriageParm object that is suitable as the carriage parameter for a xmlrpc_c::client_xml client that uses the xmlrpc_c::xmlTransport_curl XML transport.

The class is derived from xmlrpc_c::carriageParm_http (which is derived from xmlrpc_c::carriageParm), and has no additional members.

In case you're wondering what the "0" is doing in the name: We expect this class to grow in future versions of Xmlrpc-c, and it may not be possible to distinguish the new versions from the old ones with variable constructor parameter lists alone. Since today's programs have to keep compiling and working as they do today, we may have to add new classes and use that number suffix to distinguish them.

Constructors

The constructor is the same as that for the base class xmlrpc_c::carriageParm_http0.

Example:


    xmlrpc_c::carriageParm_curl0 const myParm("http://localhost:8080/RPC2");

useUnixSocket Method

This makes the transaction use a Unix socket instead of a TCP/IP socket and identifies the Unix socket to use. This means the transaction will not be true HTTP and therefore not true XML-RPC. It also means the URL (though still required) does not determine what server is accessed. (A Unix socket communicates with whatever server, which must be within the same OS image, is listening on that same socket).

Prototype:


    void
    useUnixSocket(std::string const socketPathName);

socketPathName is the path name (i.e. file name) of the socket to use.

This function was new in Xmlrpc-c 1.63 (June 2024).

Class xmlrpc_c::carriageParm_curl0Ptr

An object of this class is a pointer to an object of class xmlrpc_c::carriageparmcurl0. This class is derived from girmem::autoObjectPtr.

Class carriageParm_libwww0

An object of this class is an xmlrpc_c::carriageParm object that is suitable as the carriage parameter for a xmlrpc_c::client_xml client that uses the xmlrpc_c::xmlTransport_libwww XML transport.

The class is derived from xmlrpc_c::carriageParm_http (which is derived from xmlrpc_c::carriageParm), and has no additional members.

In case you're wondering what the "0" is doing in the name: We expect this class to grow in future versions of Xmlrpc-c, and it may not be possible to distinguish the new versions from the old ones with variable constructor parameter lists alone. Since today's programs have to keep compiling and working as they do today, we may have to add new classes and use that number suffix to distinguish them.

Constructors

The constructor is the same as that for the base class xmlrpc_c::carriageParm_http0.

Example:


    xmlrpc_c::carriageParm_curl0 const myParm("http://localhost:8080/RPC2");

Class xmlrpc_c::carriageParm_libwww0Ptr

An object of this class is a pointer to an object of class xmlrpc_c::carriageparmlibwww0. This class is derived from girmem::autoObjectPtr.

Class carriageParm_wininet0

An object of this class is an xmlrpc_c::carriageParm object that is suitable as the carriage parameter for a xmlrpc_c::client_xml client that uses the xmlrpc_c::xmlTransport_wininet XML transport.

The class is derived from xmlrpc_c::carriageParm_http (which is derived from xmlrpc_c::carriageParm), and has no additional members.

In case you're wondering what the "0" is doing in the name: We expect this class to grow in future versions of Xmlrpc-c, and it may not be possible to distinguish the new versions from the old ones with variable constructor parameter lists alone. Since today's programs have to keep compiling and working as they do today, we may have to add new classes and use that number suffix to distinguish them.

Constructors

The constructor is the same as that for the base class xmlrpc_c::carriageParm_http0.

Example:


    xmlrpc_c::carriageParm_wininet0 const myParm("http://localhost:8080/RPC2");

Class xmlrpc_c::carriageParm_wininet0Ptr

An object of this class is a pointer to an object of class xmlrpc_c::carriageparmwininet0. This class is derived from girmem::autoObjectPtr.

Class carriageParm_pstream

An object of this class is an xmlrpc_c::carriageParm object that is suitable as the carriage parameter for a xmlrpc_c::client_xml client that uses an xmlrpc_c::xmlTransport_pstream XML transport.

The class is derived from xmlrpc_c::carriageParm and has no additional members.

Notice that there are no members you can set. The xmlTransport_pstream class is so simple that there is only one way to carry an RPC with it. Even the destination of an RPC is a fixed characteristic of the transport object. So the only reason this class exists is is to fill a place in the argument list of some methods that are designed for use with more flexible transport classes.

This class was new in Xmlrpc-c 1.11 (June 2007).

Class xmlrpc_c::carriageParm_pstreamPtr

An object of this class is a pointer to an object of class xmlrpc_c::carriageparmpstream. This class is derived from girmem::autoObjectPtr.

This class was new in Xmlrpc-c 1.11 (June 2007).

Class xmlrpc_c::connection

An object of this class represents a sort of channel over which RPCs execute. It has two fixed ends and a fixed medium. It is really nothing more than a combination of a client object and a carriage parameter object. If you do many RPCs to the same server in the same way, this can save you a little program clutter.

Class xmlrpc_c::serverAccessor is usually what you want instead of this.

Constructors

Prototype:


    connection(xmlrpc_c::client *       clientP,
               xmlrpc_c::carriageParm * carriageParmP);

Class xmlrpc_c::serverAccessor

An object of this class is a tool for making RPCs to a particular XML_RPC server, carried a particular way. Internally, it uses an xmlrpc_c::client and an xmlrpc_c::carriage_parm. You get only a simple synchronous "call" interface;

You could just use your own client and carriage parameter, but a server accessor hides the carriage parameter mess from the parts of your code that do RPCs, thus making that code cleaner.

Example:


    string const serverUrl("http://localhost:8080/RPC2");
    string const methodName("sample.add");

    clientXmlTransportPtr const transportP(new clientXmlTransport_curl(
        clientXmlTransport_curl::constrOpt()));
    clientPtr const clientP(new client_xml(transportP));
    carriageParm_curl0Ptr const carriageParmP(
        new carriageParm_curl0(serverUrl);
    serverAccessor const serverP(clientP, carriageParmP);

    ...

    rpcOutcome outcome;
        
    serverP->call(methodName, ParamList().add(value_int(5).add(value_int(7),
                  &outcome);

This class was new in Xmlrpc-c Release 1.04 (November 2005).

Constructors

Prototype:


    serverAccessor(xmlrpc_c::clientPtr       clientP,
                   xmlrpc_c::carriageParmPtr carriageParmP);

This constructs a server accessor object that uses the client pointed to by clientP to perform RPCs on the server identified by carriageParmP.

call Method

Prototype:


    void
    call(std::string          & methodName,
         xmlrpc_c::paramList  & paramList,
         xmlrpc_c::rpcOutcome * outcomeP);

This performs an RPC. It makes a call and waits for the response, analogous to the call method of the client, and rpc classes.

Interrupting

There is a facility for interrupting long-running methods with a signal. It is analogous, in purpose and form, to the same facility for the C library.

In C++, you use the setInterrupt method of the client object where in C you would use the xmlrpc_client_set_interrupt() function. In C++, an interrupted method throws an error.

Dealing With Broken Servers

Considerations for dealing with broken servers are the same as for the C interface.

Debugging

This section describes some facilities and techniques for debugging programs that use libxmlrpc_client++.

Standard Error

The trace facilities described here write messages to the Standard Error file descriptor via the Standard Error stream of the standard C library (stderr). So make sure you have one. Many server processes don't (they explicitly close the one that the system setup code provides).

XMLRPC_TRACE_XML environment variable

If you set the XMLRPC_TRACE_XML environment variable to 1, the libxmlrpc_client transports will print to Standard Error the XML of the call and of the response, in addition to their normal processing.

It works the same as for the C client library.

XMLRPC_TRACE_CURL environment variable

If you are using the Curl XML transport, XMLRPC_TRACE_CURL can be useful.

It works the same as for the C client library.

XMLRPC_TRACE_PACKETSOCKET environment variable

If you are using the packet stream XML transport, XMLRPC_TRACE_PACKETSOCKET can be useful.

It works the same as for the server library.