tag:blogger.com,1999:blog-152608742024-02-20T14:00:30.947-05:00The blog that is [mX]Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-15260874.post-50464853259309108912012-03-26T09:50:00.001-04:002012-03-26T18:40:32.564-04:00qjsonrpc round 2hey, just wanted to give you all an update on where QJsonRpc is at, and give an example of how to actually use it. When I first blogged about it we had a functional backport of the QJson code from Qt 5, and the beginnings of the service framework worked out. There has been a lot of progress on the library since then and things are looking a lot more useable. Here's a quick breakdown (and some background for those not up to speed on these technologies):<br />
<br />
<h3>
<span style="font-size: large;"><b>the problem</b></span></h3>
Qt provides a great solution for interprocess communication (IPC) and remote procedure calls (RPC) in the form of bindings to the D-Bus message bus system (QtDBus). Unfortunately, the QtDBus primarily targets unix-based operating systems. While ports do exist for other operating systems (notably the windows port that has been merged into the D-Bus mainline), they are not necessarily complete and are not quite up to par with the unix implementation. Furthermore, it could be argued that D-Bus is a bit "heavy" for most IPC/RPC needs, in that it was originally designed for communication between system processes (hardware drivers, or printers for example) and user-land processes. Not to mention it requires another compiler to generate code for its interfaces. Enter QJsonRpc...<br />
<br />
<h3>
<span style="font-size: large;"><b>
the (partial) solution</b></span></h3>
QJsonRpc is not a full IPC solution (read: NOT a complete replacement for D-Bus). QJsonRpc implements the JSON-RPC 2.0 specification using Qt-based classes. JSON-RPC is a derivative of XML-RPC providing a means of calling a method on a remote object and receiving a response. Why JSON over XML? This is probably not the best place to get into this (ajaxian has some nice articles about this: http://ajaxian.com/archives/json-vs-xml-the-debate), JSON just happens to be the solution that works best for my particular problem domain. Oh, and its real chic these days, am I right? I work with a product that requires direct interaction with web services and, for better or worse, JSON seems to be winning in that department.<br />
<br />
<h3>
<span style="font-size: large;"><b>
how do I use this thing?</b></span></h3>
I'm glad you asked! QJsonRpc leverages the Qt meta object system to provide a rapid solution to your RPC needs. QJsonRpc services are just QObject's that define a "serviceName" and a number of methods you can call on that service.<br />
<br />
Here's what a very simple service provider (server) would look like:<br />
<pre><span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><QCoreApplication></span>
<span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><QTime></span>
<span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;">"qjsonrpcservice.h"</span>
<span style="color: olive;">class</span><span style="color: silver;"> </span><span style="color: purple;">TestService</span><span style="color: silver;"> </span>:<span style="color: silver;"> </span><span style="color: olive;">public</span><span style="color: silver;"> </span><span style="color: purple;">QJsonRpcService</span>
{
<span style="color: silver;"> </span><span style="color: purple;">Q_OBJECT</span>
<span style="color: silver;"> </span><span style="color: purple;">Q_CLASSINFO</span>(<span style="color: green;">"serviceName"</span>,<span style="color: silver;"> </span><span style="color: green;">"service"</span>)
<span style="color: olive;">public</span>:
<span style="color: silver;"> </span><span style="color: purple;">TestService</span>(<span style="color: purple;">QObject</span><span style="color: silver;"> </span>*parent<span style="color: silver;"> </span>=<span style="color: silver;"> </span><span style="color: navy;">0</span>) :<span style="color: silver;"> </span><span style="color: purple;">QJsonRpcService</span>(parent)<span style="color: silver;"> </span>{}
<span style="color: olive;">public</span><span style="color: silver;"> </span><span style="color: purple;">Q_SLOTS</span>:
<span style="color: silver;"> </span><span style="color: purple;">QString</span><span style="color: silver;"> </span>currentTime()<span style="color: silver;"> </span>{<span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span><span style="color: purple;">QTime</span>::currentTime().toString();<span style="color: silver;"> </span>}
};
<span style="color: olive;">int</span><span style="color: silver;"> </span>main(<span style="color: olive;">int</span><span style="color: silver;"> </span>argc,<span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>**argv)
{
<span style="color: silver;"> </span><span style="color: purple;">QCoreApplication</span><span style="color: silver;"> </span>app(argc,<span style="color: silver;"> </span>argv);
<span style="color: silver;"> </span><span style="color: purple;">QJsonRpcLocalServiceProvider</span><span style="color: silver;"> </span>rpcServer;
<span style="color: silver;"> </span>rpcServer.addService(<span style="color: olive;">new</span><span style="color: silver;"> </span><span style="color: purple;">TestService</span>);
<span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span>(!rpcServer.listen(<span style="color: green;">"/tmp/testservice"</span>))<span style="color: silver;"> </span>{
<span style="color: silver;"> </span>qDebug()<span style="color: silver;"> </span><<<span style="color: silver;"> </span><span style="color: green;">"can't</span><span style="color: silver;"> </span><span style="color: green;">start</span><span style="color: silver;"> </span><span style="color: green;">local</span><span style="color: silver;"> </span><span style="color: green;">server:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><<<span style="color: silver;"> </span>rpcServer.<span style="font-style: italic;">errorString</span>();
<span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span>-<span style="color: navy;">1</span>;
<span style="color: silver;"> </span>}
<span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span>app.exec();
}
<span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;">"server.moc"</span>
</pre>
<pre></pre>
<pre></pre>
And here's what the corresponding client would look like:<br />
<pre><span style="color: navy;">#</span><span style="color: navy;">include</span><span style="color: silver;"> </span><span style="color: green;"><QCoreApplication></span>
<span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;"><QLocalSocket></span>
<span style="color: navy;">#include</span><span style="color: silver;"> </span><span style="color: green;">"qjsonrpcservice.h"</span>
<span style="color: olive;">int</span><span style="color: silver;"> </span>main(<span style="color: olive;">int</span><span style="color: silver;"> </span>argc,<span style="color: silver;"> </span><span style="color: olive;">char</span><span style="color: silver;"> </span>**argv)
{
<span style="color: silver;"> </span><span style="color: purple;">QCoreApplication</span><span style="color: silver;"> </span>app(argc,<span style="color: silver;"> </span>argv);
<span style="color: silver;"> </span><span style="color: purple;">QLocalSocket</span><span style="color: silver;"> </span>socket;
<span style="color: silver;"> </span>socket.connectToServer(<span style="color: green;">"/tmp/testservice"</span>);
<span style="color: silver;"> </span><span style="color: olive;">if</span><span style="color: silver;"> </span>(!socket.waitForConnected())<span style="color: silver;"> </span>{
<span style="color: silver;"> </span>qDebug()<span style="color: silver;"> </span><<<span style="color: silver;"> </span><span style="color: green;">"couldn't</span><span style="color: silver;"> </span><span style="color: green;">connect</span><span style="color: silver;"> </span><span style="color: green;">to</span><span style="color: silver;"> </span><span style="color: green;">local</span><span style="color: silver;"> </span><span style="color: green;">server:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><<<span style="color: silver;"> </span>socket.errorString();
<span style="color: silver;"> </span><span style="color: olive;">return</span><span style="color: silver;"> </span>-<span style="color: navy;">1</span>;
<span style="color: silver;"> </span>}
<span style="color: silver;"> </span><span style="color: purple;">QEventLoop</span><span style="color: silver;"> </span>loop;
<span style="color: silver;"> </span><span style="color: purple;">QJsonRpcServiceSocket</span><span style="color: silver;"> </span>service(&socket);
<span style="color: silver;"> </span><span style="color: purple;">QJsonRpcServiceReply</span><span style="color: silver;"> </span>*reply<span style="color: silver;"> </span>=<span style="color: silver;"> </span>service.invokeRemoteMethod(<span style="color: green;">"</span><span style="color: green;">service.</span><span style="color: green;">currentTime"</span>);
<span style="color: silver;"> </span><span style="color: purple;">QObject</span>::connect(reply,<span style="color: silver;"> </span><span style="color: olive;">SIGNAL</span>(finished()),<span style="color: silver;"> </span>&loop,<span style="color: silver;"> </span><span style="color: olive;">SLOT</span>(quit()));
<span style="color: silver;"> </span>loop.exec();
<span style="color: silver;"> </span>qDebug()<span style="color: silver;"> </span><<<span style="color: silver;"> </span><span style="color: green;">"response:</span><span style="color: silver;"> </span><span style="color: green;">"</span><span style="color: silver;"> </span><<<span style="color: silver;"> </span>reply->response();
}
</pre>
And here's what that same client code looks like in python (I just grabbed this implementation: http://www.simple-is-better.org/rpc/index.html):<br />
<pre><span style="color: navy;">import </span>jsonrpc
<span style="color: navy;">import</span> socket
rpc = jsonrpc.ServerProxy(jsonrpc.JsonRpc20(),
jsonrpc.TransportSocket(addr=<span style="color: green;">"/tmp/testservice"</span>,
sock_type=socket.AF_UNIX))
<span style="color: navy;">print</span> rpc.service.currentTime()
</pre>
<pre></pre>
cool stuff<br />
<br />
<h3>
<span style="font-size: large;"><b>some extra details...</b></span></h3>
I just wanted to address some issues from comments to my previous post here:<br />
<ul>
<li>What about TCP support?</li>
<ul>
<li>we've got that now. ssl sockets should work just fine as well</li>
</ul>
<li>What about using QJsonRpcMessage over QSharedMemory</li>
<li>What about an HTTP interface to QJsonRpcService</li>
<ul>
<li>I've chosen to leave these up to the community, I just don't have a need for these at the moment.</li>
</ul>
<li>Are you going to submit this upstream for inclusion in Qt 5.1?</li>
<ul>
<li>Yeah, I think this would be a great idea. JSON solutions seem to be sneaking into Qt 5.1 (JsonDB, JsonStream, the QJson classes themselves), so I think there's precedent here. Would you use this? Let me know.. </li>
</ul>
<li>Unfortunately, in order to support interaction with other jsonrpc libraries (specifically the reference jsonrpc python library I've been using), we can't use Qt's binary json format over the wire. Also, the QJson classes (as of the writing of this post) don't allow for modification of the JSON output, so I can't really cut down on all the white space. Hopefully, we can fix all of this relatively soon either through the use of JsonStream or through a patch to the QJson classes. </li>
</ul>
<br />
<h3>
<span style="font-size: large;"><b>
what's next</b></span></h3>
as of right now we have a functional implementation of JSONRPC 2.0, and for a case in which you you need to call methods on one side, this solution works quite well. What if both sides of the wire need to provide invokable interfaces? An easy solution with the current code would be to create QJsonRpcServiceProviders on both sides, but I think it would be nicer to provide a unified QJsonRpcServicePeer that encapsulates a QJsonRpcServiceSocket and QJsonRpcServiceProvider under one roof.<br />
<br />
<b><span style="font-size: large;">thanks</span></b><br />
<br />
<ul>
<li>Peter Kümmel for help getting this all working on windows</li>
<li>Matt Godshall (<a href="http://mgodshall.wordpress.com/">http://mgodshall.wordpress.com/</a>) for help improving the autotests for the library!</li>
<li>Yuval Tal for reminding me to keep up to date with the QJson bug fixes </li>
</ul>Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com20tag:blogger.com,1999:blog-15260874.post-84273604246551456942012-03-03T22:15:00.001-05:002012-03-13T13:45:59.991-04:00qjsonrpcRecently I've been working on a qt-based project at work that requires ipc in a number of parts of the system. Since we're using Qt this was no problem, we have qdbus right? Unfortunately, qdbus only actively supports unix at this time so that's not an option for our cross-platform solution. Instead of qdbus, we had been using Qxt's rpc peers, and that was okay for initial prototypes but required an adaptor to connect to our web interface. Since our web interface is the primary control point for the system, this was also not ideal. So instead I went about looking for a json alternative, and qjsonrpc was born.<br />
<br />
qjsonrpc utilizes the new json classes included as part of qt5 to implement the jsonrpc 2.0 specification. Currently, the project provides a QJsonRpcMessage class as well as a way to setup a simple QLocalServer/QLocalSocket rpc service. The project also includes a backport of the qt5 json classes to qt 4.7.4. I can't take too much credit here, most of the heavy lifting was done by the trolls as usual (thanks Lars for the json classes, and Thiago for his guidance and inspiration from qdbus!), but hopefully the code is useful to others out there.<br />
<br />
It should be mentioned that there are a few alternative jsonrpc solutions for Qt (libmaia, phobos, jsonqt), but I don't believe any of them include support for connection between the messages and QObject's slots (a la qdbus, qxtrpc). I also was interested in writing something that used the new json classes, as those are now part of the qt family and will continue to be supported in the future.<br />
<br />
Below are links to the code repo, as well as a wiki/tracker for the project (graciously hosted by Etienne Savard over at Symbiosoft):<br />
<ul>
<li><a href="https://gitorious.org/qjsonrpc">https://gitorious.org/qjsonrpc</a></li>
<li><a href="http://symbiosoft.net/projects/qjsonrpc">http://symbiosoft.net/projects/qjsonrpc</a></li>
</ul>
<br />
Happy hackingAnonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com6tag:blogger.com,1999:blog-15260874.post-1157149430944569692006-09-01T18:12:00.000-04:002012-03-13T13:45:19.109-04:00That darned QToolBoxThe other day I was spending some time working on stylizing a personal project of mine when I came across that darned QToolBox. While this is an extremely useful widget (IMHO), the thing is just plain and simple one of the ugliest widgets Qt provides, good lord 1995 called and wants its style back ;) Anyway I spent some time trying to change the way it looked through QStyle's and that wasn't cutting it. After submitting a feature request to Trolltech (for drawing the background of the toolbox) and realizing its just not going to make it into Qt any time soon, I spent a little time yesterday making what I tentatively call the KToolBox:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3122/1407/1600/snapshot2.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3122/1407/320/snapshot2.png" alt="" border="0" /></a>Basically its a cuter (pun intended) version of the QToolBox, that I think looks MUCH better than the widget its intended to replace. Hey, hopefully people will actually use toolbox's in their applications now (hint: try a 'grep -HRI "QToolBox" ./*' in kdebase or kdelibs...). There are still a number of issues with it, but its mostly usable - if anyone is interested in using it or helping work kinks out of it please contact me (either here or on irc), otherwise I'll be submitting a RFC on k-c-d for adding it to kdeui soon.Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com3tag:blogger.com,1999:blog-15260874.post-1139257439448740142006-02-06T15:19:00.000-05:002012-03-13T13:45:28.120-04:00kjsembed and wikiThis isn't going to be a long one, but I just wanted to let people know that the newly ported kjsembed as well as the new plasma wiki have been released!<br /><br />I've ported Ian Geiser's (new) KJSEmbed to use the recently merged KJS from Apple. Things seem to build and work kosher with the tests currently in place, so now it's time for all you guys to play around with it and tell us when and where it breaks!<br /><br />Regarding the wiki (http://plasma.kde.org/wiki), it was originally using dokuwiki but that proved to be not so capable of our needs. Therefore, the wiki has been moved over to MediaWiki and old posting have been merged. What's more, I made a KDE skin for MediaWiki, ervin has been using it for Solid as well (check the solid link on the plasma page if you're interested). Send me an email if you're interested in it. I'd also like to thank pinheiro very much for once again coming in for the rescue and making the wiki logo, thanks man!<br /><br />I hope either of these releases interest some people because feedback is always very very nice. Enjoy!Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com4tag:blogger.com,1999:blog-15260874.post-1138302281648313632006-01-26T13:56:00.000-05:002006-01-26T14:15:12.720-05:00Ole!Man it's been a while since I last blogged, things have been busy busy busy.<br /><br />Before I move on to all that, I wanted to let people know I ported Ian Geiser's new qt4 kjsembed to the kde build system and it's now living in branches/work/kde4/playground/bindings. It doesn't currently build against Apple's new KJS (in trunk/kdelibs), but it should (hopefully) still build against the KJS in kdelibs4_snapshot. Hopefully we'll get around to making it work with the new KJS in the coming weeks.<br /><br />Anyway, back to life.. I've spent the past three weeks living up in Exton, PA working for the oh-so-famous SourceXtreme, and what a great time that was! Much thanks to Ian and Jason Nocks for taking a college a student on such short notice for such a short amount of time, but the experience was invaluable. I learned a lot about different (and perhaps initially uncomfortable ;) ) programming practices/philosophies, as well as first hand experience at what it's like coding for a living, dealing with customers etc. All in all it was a blast, not to mention the weeks of hack fests on the also infamous couch de Geiser (that basement is definitely not as cold as people like to claim!), thanks Ian and his wife for letting me crash there (say hi to the cats for me heh).<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/3122/1407/1600/itemdelegate.2.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/3122/1407/320/itemdelegate.2.jpg" alt="" border="0" /></a>Lastly, I've been working on a lot of kjsembed/plasma stuff the past few months, but I've also been working on some personal projects, particularly something for a friends company. Part of the project includes an image viewer so I started playing around with Qt4's interview. After a few days of tweaking (and enough chatting with zack and ian) I've come up with this little app. Note the sexy drop shadows (ok well they are a little less than beautiful right now! gimme a break :) ), they are generated on the fly by the QItemDelegate for the QListView, very cool!Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com0tag:blogger.com,1999:blog-15260874.post-1125769828384021752005-09-03T13:36:00.000-04:002012-03-13T13:45:33.985-04:00SuperKarambaPlasma development on the kicker side has reached a pretty solid ported stage, and what with all the excitement going on in Malaga it seemed like a good time to refocus onto another part of Plasma; namely, SuperKaramba. There's been a lot of talking going on about SuperKaramba within our community, trying to best approach the problem of refactoring its code and eventually merging it into Plasma. Luckily, we have some hard working developers ready and willing to tackle such a problem! Ryan Nickell, Pedro Suarez and a newcomer Vinay Khaitan (he's been working his butt off) are all looking into making this happen. Don't you love it when we all just work together :)<br /><br />Anyway, if you're interested in working on SuperKaramba, or just want to learn of its future, especially regarding Plasma, then pop into #SuperKaramba on freenode this Sunday at 10:00EST, we'll be having a discussion.Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com0tag:blogger.com,1999:blog-15260874.post-1124231185377746452005-08-16T17:57:00.000-04:002012-03-13T13:45:39.886-04:00plasma devwiki<a style="font-size: 37px;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://plasma.kde.org/wiki"><img src="http://plasma.kde.org/wiki/lib/tpl/plasma/images/devwiki-down.png" alt="" class="showonplanet" border="0" width=400px /></a><br /><br /><div style="text-align: left;">I'm pleased to announce the opening of the plasma developer wiki!<br /><br />We've opened up this wiki in a decided effort to resolve the issue of "too many cooks in the kitchen." Up until now tracking the progress of the plethora of ideas revolving around Plasma has been somewhat troublesome, as they are scattered throughout the usual channels (IRC, mailing list, kde-artists forum). Unfortunately, this has lead to some confusion with our prospective, and more importantly, current developers! Hopefully this resource can be used effectively to clarify, and expedite, the formation of this beast of a project.<br /><br />I'd especially like to thank hon (Ali Honarvar) for the work he did on creating the graphics for the site, he worked really hard on this and put up with a lot of "critique" (how many drafts were there? 30? hehe).<br /><br />The site is currently pretty sparse, but that's where the users come in :-) I started a little bit of my personal developer page showing off some of my work on Extenders, and Aaron has been filling out the news section as time permits, but it's really up to the community to use this or not at this point. I, for one, hope we do!<br /><br />Click on the image above to get to the wiki, there is also a link in the "Links" section of my blog.<br /><br />Cheers<br /></div>Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com1tag:blogger.com,1999:blog-15260874.post-1123608252050749452005-08-10T01:16:00.000-04:002005-08-09T22:19:04.303-04:00first entryHello hello, allow me to introduce myself. My name is Matt ([mX] to my friends on freenode) and I am, among other things, a KDE hacker. I've been working on KDE for about a year now (though I've decidedly picked up the pace over the past few months) and have spent most of that time working on our beloved Kicker. And what fun that has been! As Kicker is slowly, but surely, evolving into Plasma I figured why not start up a blog to keep track? Here goes nothing!Anonymoushttp://www.blogger.com/profile/04895443201262021652noreply@blogger.com2