Wiedi in Wonderland

libmaia: XML-RPC with Qt4

Sat 08 March 2008

So, now that my exams are all done I finally found some time to put up a library you might find useful.
Two semesters ago Karl Glatz and I both needed a XML-RPC library for Trolltechs Qt 4.

Qt4

We first looked around what was already there:

  • QuteXR: a very good lib implementing the server and client side. Sadly only Qt 3. Has many features and so wasn't easy to port over to Qt4 in the short time we had for our Projects.
  • KRPC: only implements the client side. But we could use some code here.
  • QxtXmlRpc: I found out about this one only recently. And also only implements the client.

So we had to create something new. Luckily we were able to use some code from KRPC and had some inspiration from QuteXR.

To demonstrate how easy it is to use libmaia: two examples.

Let's create a Server first using these simple lines of code:
QLineEdit *sometext = new QLineEdit(this);
MaiaXmlRpcServer *server = new MaiaXmlRpcServer(8080, this);
server->addMethod("examples.displaytext", sometext, "setText");

First we create a QLineEdit for demonstration purpose.
Then we start the XmlRpc Server on port 8080.
In line 3 we register the Method "examples.displaytext" to the QLineEdits slot "setText".
You can now remotely call "examples.displaytext" with a String as parameter and change the content of your LineEdit.

Now create a client:
MaiaXmlRpcClient *rpc = new MaiaXmlRpcClient(QUrl("http://localhost:8080/RPC2"), this);
rpc->call("examples.displaytext", QDateTime::currentDateTime().toString("hh:mm:ss"),
this, SLOT(testResponse(QVariant &)),
this, SLOT(testFault(int, const QString &)));

Here we create the client object by passing the server URL to the constructor.
Calling a Method is as easy as passing its name, the arguments and two slots to the "call" method.
The first of the two slots is used to handle the response, the second can be used to catch errors.

Looks easy to get started with? Right, so clone directly from github here:

git clone https://github.com/wiedi/libmaia.git

You'll also find further examples there.

Have fun with it :)


Comments

  • dz:

    2008-04-24 08:33:25+02:00

    The lib is really nice, thx a lot.

    but in the spec of xmlrpc the date is not so formated, like qt does!

    in libMaia - maiaObject.cpp

    } case QVariant::DateTime: {
        //QString textValue = arg.toDateTime().toString(Qt::ISODate);
        QString textValue = arg.toDateTime().toString("yyyyMMddThh:mm:ss");
    

    Best regards dz

  • wiedi:

    2008-04-24 23:12:35+02:00

    Oh, thanks, i'll fix it :)

  • dz:

    2008-04-25 12:28:46+02:00

    Wie ist es am sinnvollsten mehrere call nacheinander zu machen. zB login -> abfrage -> logout. ohne über die response Funktion das nächste zu triggern. zu ne Art Queue?

    dz

  • wiedi:

    2008-05-20 22:58:54+02:00

    Hmmm Login->Abfrage->Logout ist glaube ich vom Prinzip her ungeschickt. Besser wäre dafür HTTP Auth zu verwenden (das kann libmaia noch nicht).

    Verkettete Calls könnte man aber an sich schon von einer Klasse managen lassen, welche die in einer Queue abarbeitet. Von der Response sollte das ja dann aber trotzdem getriggert werden, sonst braucht man ja keine Queue.

    Die Queue Klasse kann auch alle Responses auf einen Slot connecten um dann weiter zu schalten, das ist ja kein Problem.

    Falls du so etwas wo implementierst oder Lust hast HTTP Auth für libmaia zu basteln ... fände ich interessant :)

  • toemaz:

    2008-05-23 19:22:24+02:00

    Thanks for sharing the lib! Do you plan to publish it somewhere in e.g. code.google.com or any other project tracker?

  • dz:

    2008-08-27 11:53:56+02:00

    Nochmal Kompliment, nette lib.

    Wenn du libmaia unter lgpl bei sourceforge hostest, wurde ich mich "HTTP Auth" und https annehmen.

  • silver:

    2008-09-26 12:05:15+02:00

    Thanks for your work! Great lib! But it has small memory leak. To fix it, edit maiaXmlRpcServerConnection.cpp file to be like

    ...
    MaiaXmlRpcServerConnection::~MaiaXmlRpcServerConnection() {
        clientConnection->deleteLater();
        delete header;
    
  • wiedi:

    2008-09-26 17:28:58+02:00

    thanks, fix committed

  • last.fm support comming to QtMPC - rullzer:

    2008-11-23 23:08:13+01:00

    [...] this we found a nice library: libmaia. Beside a small bug I found (which reminds me I have to report it upstream). This works very well. [...]

  • rullzer:

    2008-12-23 21:56:05+01:00

    I noticed a small error. You put true/false between the tags. However according to the specs this should just be 0/1

    Other than that this is a great lib :D

  • dz:

    2009-03-02 08:41:31+01:00

    Hi wiedi,

    you get a good feedback from everywhere. If the library would be LGPL licensed it would be fantastic. ..

  • wiedi:

    2009-03-08 20:35:18+01:00

    @rullrer: thanks for reporting, you're right. Will fix that soon. Nice to see it getting integrated into a great project like QtMPC :)

    @dz: I can give you the permission to use it under the LGPL, except for the maiaObject.cpp/.h files. I think you already tried to contact the original authors - as did I - and did not get any response. :/ So you can either rewrite that part from scratch or use it under the current BSD-style license.

    I also have some patches here around for SSL and HTTP-Auth support that I'll merge when I find the time :)

  • letux:

    2009-03-12 07:55:50+01:00

    Hi wiedi,

    really nice lib, but this comment is not new for you ;-)

    I modified the following code in the MaiaXmlRpcClient file in the call function:

    QHttpRequestHeader header("GET", m_url.toEncoded());
    

    In this case, we can call web service by adding some URL parameters sent by GET. I used your lib with a php server web service. Maybe it could be interesting to have the flexibility to set the method and to add post or get parameter.

    thanks again

  • Leland:

    2009-11-27 08:00:29+01:00

    Thanks for the lib! Just a minor comment though: performance of the lib seems rather slow if there are multiple consecutive calls to the same server. Testing with perl for the same series of calls has a rapid response. In general, with this lib it appears that it seems to wait between 20 and 30 seconds between each call to the same server.

    Is this deliberate behaviour, or is there a parameter that can be passed to decrease what appears to be a timeout limit?

    Thanks,

    L.

  • Leland:

    2009-12-04 07:26:51+01:00

    Just another note.. our XMLRPC responses include some text in UTF-8 encoding from the server (server is not based on libmaia). However, rendering the text on the client side using libmaia has a character encoding issue and cannot be displayed properly.

  • Martin Scheffler:

    2010-02-10 15:54:53+01:00

    Hi, got another small fix.

    WS-XMLRPC sends strings as mytext instead of mytext which they say is valid syntax.

    LibMaia does not currently handle this. http://ws.apache.org/xmlrpc/faq.html#string_format

    Fix: In maiaObject.cpp:

    QVariant MaiaObject::fromXml(const QDomElement &elem) {
        if(elem.tagName().toLower() != "value") {
            return QVariant();
        }
    
        if(!elem.firstChild().isElement())
        {
            return QVariant(elem.text());
        }
    
        const QDomElement typeElement = elem.firstChild().toElement();
        (...)
    

    That should do it.

    Keep up the good work!

  • Jan Schlichting:

    2010-03-02 09:34:43+01:00

    Dear Wiedi, I was wondering if I could get LGPL licence as well. I would appreciate if you could get in contact with me via mail. Thanks a lot in advance, Greetings from Kiel Jan

  • Gouranga:

    2010-03-09 09:06:57+01:00

    Hi, tolle Lib! Leider gibs ein kleines Memoryleak im Client, zumindest in 4.6.2: Der QNetworkAccessManager möchte bei mir die replys selber löschen, delete rply im finished Slot führt daher zu ner Access Violation. Desweiteren wäre es schön, wenn du die Patches zu SSL und HTTP Auth einpflegen würdest. Ich meine das ist ja quasi support, man muss nur hier und da ein bisschen kitzeln :-)

    Ach übrings der Link zum WebSVN ist kaputt

  • wiedi:

    2010-03-09 20:08:40+01:00

    @letux: in the spec it states "An XML-RPC message is an HTTP-POST request." I think you can send URL parameters even in POST requests. So I'm not sure if this functionality is really needed.

    @Martin: fixed, thanks

    @Leland: i'll look into it

    @Jan and others regarding GPL: libmaia is under the FreeBSD License, which is GPL compatible. So you can use it in LGPL/GPL projects.

    @Gouranga: das löschen von replys müsste gefixed sein. HTTPS und HTTP Auth im client sollte bereits gehen in dem man als URL https://user:pass@example.com verwendet.

  • Murilo Ito:

    2010-03-10 17:52:56+01:00

    @Leland: To fix it, just change inside MaiaXmlRpcServerConnection::readFromSocket method (maiaXmlRpcServerConnection.cpp):

    -parseCall( clientConnection->readAll() );
    +parseCall( QString::fromUtf8(clientConnection->readAll()) );
    

    regards,

    Murilo Ito.

  • Leland:

    2010-03-12 08:04:16+01:00

    @Murilo: Thanks for the tip.. works fine. Now if only I can figure out the previous one (slow reaction for multiple requests to same server)...

    Leland

  • Werner:

    2010-10-17 10:59:36+02:00

    Hi,

    die beiden Konstruktoren MaiaXmlRpcServer::MaiaXmlRpcServer initialisieren die Variable "allowedAddresses" nicht. Im Normalfall passiert dadurch nix, aber bei mir gab es Fehler. Also besser:

    allowedAddresses(NULL)
    

    zur Initialisierung bei beiden Konstruktoren hunzufügen.

    Viele Grüße Werner

  • Leland:

    2010-10-25 08:23:46+02:00

    Is there any plan to include HTTPS/SSL support with this lib? I have an application that requires (obligatory) the XMLRPC session to be over HTTPS. Despite passing the URL as https, it still tries to connect using http.

    Thanks,

    Leland

  • Leland:

    2010-10-25 11:23:52+02:00

    Managed to patch it for the client side myself. Weidi, can I submit a patch to you for this?

  • wiedi:

    2010-10-25 23:30:40+02:00

    @Werner: allowedAddresses wird jetzt immer auf NULL gesetzt.

    @Leland: HTTPS/SSL support for the server would be nice. I'll look into it if I find the time. The more recent versions of the client should already support SSL by just passing the URL with the https schema. Can you retry with the current version from svn please? I'll reply to your emails in a second :D

    And patches are of course always welcome :)

  • Vladimir:

    2010-11-22 23:03:11+01:00

    A dirty patch for authorize connect: (http://pastebin.com/ekD2pKgR)

    Index: maiaXmlRpcClient.cpp
    ===================================================================
    --- maiaXmlRpcClient.cpp        (revision 18)
    +++ maiaXmlRpcClient.cpp        (working copy)
    @@ -37,6 +37,13 @@
     MaiaXmlRpcClient::MaiaXmlRpcClient(QUrl url, QObject* parent) : QObject(parent),
            manager(this), request(url)
     {
    +        if( url.userName().length() > 0 ) {
    +            //create autorization
    +            QString     s = url.userName() + QString(":") + url.password();
    +            QByteArray cs = "Basic " + s.toAscii().toBase64();
    +            request.setRawHeader("Authorization", cs);
    +            //qDebug()
    
  • chapman55k:

    2011-04-21 16:40:57+02:00

    Your stuff is great. Got it downloaded an up and running (client only) in a couple of hours. Congratulations, you have provided a great little library. I will be back.

  • XML-RPC with Qt4 - XML Tutorial:

    2011-06-13 15:16:45+02:00

    [...] Here is a good tutorial show you about XML-RPC with Qt4: So, now that my exams are all done I finally found some time to put up a library you might find useful. Two semesters ago Karl Glatz and I both needed a XML-RPC library for Trolltechs Qt 4. [...]