Mikael Hallendal, Imendio AB
Introduction
In this article I will give a quick glance on what Jabber is and how you can use a library called Loudmouth to develop applications that makes use of Jabber for communication.
Brief introduction to Jabber
Jabber is a protocol for presence and notification. It started out as a chat protocol (like ICQ, AIM, MSN) with the big difference that it was designed to bridge all of the other chat protocols together. That is, Jabber was designed to be able to speak to ICQ, AIM, MSN and other non-open protocols. This is done through server-side transports and to the client developer it is transparent whether a message is sent to an ICQ contact or another Jabber contact.
Jabber is XML based and one connection maps to an XML document. This is a very beautiful and extensible design and makes Jabber very powerful for other things than chatting.
Introduction to Loudmouth
Loudmouth is a small and lightweight library written in C. It is designed to be easy to use while not hiding the full power of the Jabber protocol. In order to use it a knowledge of the Jabber protocol is needed.
By using loudmouth the user doesn't have to know that the underlying protocol uses XML to send the messages. The user does however need to know that Loudmouth uses a tree based design for messages (which corresponds to the XML nodes which is sent over the wire). We will later see that a loudmouth message corresponds to the XML node that is sent between the server and the client.
Installing Loudmouth
Loudmouth can be downloaded from here.
Loudmouth has two requirements, GLib 2.0 and GnuTLS (optional). Loudmouth uses GLib to not have to reproduce data structures and get a better platform independency. This means that Loudmouth works or will work with small modifications on any platform where GLib is available. It's been successfully tested on Linux, Mac OSX and Windows.
When secure communication through SSL is required Loudmouth uses the GnuTLS library. It's most likely a good idea to make sure this is installed so that the Loudmouth library is built with this support.
Using Loudmouth
As mentioned earlier a loudmouth message (LmMessage) corresponds to an XML node. For example:
<message type="chat" to="foo@jabber.bar.com">; <body>My text</body> </message>
which is a jabber message sent to foo@jabber.bar.com with text "My text" corresponds to:
LmMessage *m = lm_message_new_with_subtype ("foo@jabber.bar.com", LM_MESSAGE_TYPE_MESSAGE, LM_MESSAGE_SUB_TYPE_CHAT); lm_message_node_add_child (m->node, "body", "My text");
as can be seen working with Loudmouth is pretty straight forward if you know the Jabber protocol. It is also very powerful since you can construct any elements you desire. As mentioned above, Jabber is very extensible and Loudmouth keeps it that way by letting the application developer construct any kind of elements and add arbitrary childs to
it.
Synchronous Code Example
All communication in Loudmouth is done through the LmConnection object. Each operation has an asynchronous mode and a synchronous mode, depending on what kind of application are being developed.
If you are writing a GUI application you most definitely want to use the asynchronous functions. That way your GUI won't freeze up while sending/receiveing messages. In some applications you might want things to happen synchronously, for example if you are writing small tools like a little program that just sends a message to a contact. This will be used for this example:
#include <loudmouth.h> int main (int argc, char **argv) { LmConnection *conn; GError *error = NULL; LmMessage *m; if (argc < 6) { g_print ("Usage: test server username password recipient message"); return -1; } conn = lm_connection_new (argv[1]); if (!lm_connection_open_and_block (conn, &error)) { g_print ("Couldn't open connection to '%s':\n%s\n", argv[1], error->message); return -1; } if (!lm_connection_authenticate_and_block (conn, argv[2], argv[3], "MyTestApp", &error)) { g_print ("Couldn't authenticate with '%s' '%s':\n%s\n", argv[2], argv[3], error->message); return -1; } m = lm_message_new (argv[4], LM_MESSAGE_TYPE_MESSAGE); lm_message_node_add_child (m->node, "body", argv[5]); if (!lm_connection_send (conn, m, &error)) { g_print ("Error while sending message to '%s':\n%s\n", argv[4], error-&message); } lm_message_unref (m); lm_connection_close (conn, NULL); lm_connection_unref (conn); return 0; }
Asynchronous Description
The above example showed how to use the synchronous APIs to send a message through Loudmouth. If you instead want to use the asynchronous APIs you will define callback functions that will be run when an operation is finished.
Here is an example:
lm-send-async.c
Conclusion
Using Loudmouth requires that you know the Jabber protocol in order to be able to construct the messages. By using Loudmouth you will get a nice C API to read and contruct the Jabber messages instead of having to work with raw XML. Further more Loudmouth handles all the communication for you letting you concentrate on your application instead.
This article only showed the synchronous API, the asynchronous API is built up on using callbacks. That will be handled in another article.
