1.3. Communicating via XML-RPC

1.3.1. The Server

A minimal implementation comprises a mechanism that waits for a call, dispatches it to the desired function and finally returns the method result.

The following examples omit error checking for ease of understanding. A connection is established and the call is processed.


  TcpIpConnection conn (0x7f000001, 32000); 1
  HttpProtocol prot(&conn);
  Dispatcher server(&prot);

  server.addMethod(&testcall,
                   "struct",
                   "testcall",
                   "int",
                   "Returns input, difference and result");

  server.addMethod(&testcall_with_many_params,
                   "struct",
                   "testcall_with_many_params",
                   Signature() << Integer() 2
                               << String()
                               << Double(),
                   "Performs action xyz");

  MethodCall call = server.waitForCall();
  MethodResponse resp = server.dispatchCall(call);
  server.sendResponse(resp);

1

Expect calls to 127.0.0.1 (known as localhost).

2

If you have methods that take more than one or two parameters it is an error prone taks to create the needed signature string manually. For that purpose there is a class Signature that handles the parameters and generates the signature strings. It is also possible to "stream-in" the parameters.

And now the method that does to real work. In the following example it just takes a number as input, adds a constant value of 1111 and returns a Struct that contains the original value, the difference and the result.


  MethodResponse testcall (const MethodCall &calldata)
  {
    Integer i = calldata.getParam(0);

    Struct st;

    st.addMember("before", i);
    st.addMember("difference", Integer(1111));
    st.addMember("after", Integer(i.getInteger()+1111));

    return MethodResponse(st);
  }

The XML-RPC method may also also be implemented as a normal class method. To access it you need some wrapper function. By using make_method this is done automatically. For convenience and clearity there is also a make_method for static class methods or simple functions.


  class TestWorker
  {
    public:

      TestWorker ()
      {}

      MethodResponse testmethod (const MethodCall &calldata) 1
      {
        ...
      }
  };

  MethodResponse testfunction (const MethodCall &calldata)  2
  {
      ....
  }

  server.addMethod(make_method(&testfunction),  3
                    Signature(Integer()),
                    "testcall_function",
                    Signature(Integer())
                          .addParam(Integer()),
                    "Testcase with a c-function");


  TestWorker worker;
  server.addMethod(make_method(worker, &TestWorker::testmethod),  4
                    Signature(Struct()),
                    "testcall_in_class_dynamic",
                    Signature(Integer()),
                    "Testcase with a dynamic method in a class");

1

Implement the XML-RPC method as a non-static method of a class.

2

Implement the XML-RPC method with a C-style function.

4

Add the method together with the according object to the server.

3

Add the function to the server. This approach also applies to static methods of a class.