Some of you might be aware that I worked on a project called TimmyOnTime. It is a product that allow you to track your time using your Instant Messaging application only. How we did it exactly? Where’s the code? Nice try! But I won’t tell you… however I will help you getting start with XMPP4r (XMPP For Ruby).
This will be a multipart article. You know, it wouldn’t be my style to talk about XMPP4R without talking about XMPP first. One thing at a time! So, this article is just about XMPP… no XMPP4r.
What is XMPP?
The eXtensible Messaging and Presence Protocol (aka as Jabber) is a protocol to exchange messages between 2 entities. Those messages are transmitted over the wire in the XML format.
Unlike MSN and AIM which are proprietary protocols/technologies, no one owns Jabber. You don’t log on THE Jabber Network like you log on MSN. When you use a Jabber client like Pidgin, Google Talk (Technically, GTalk is not a jabber client… but we won’t go into this) or Gajim, you log on SOME Jabber server. You could even setup your own Jabber server. It doesn’t matter because these servers can talk to each other (but are not forced to… private jabber servers are pretty common). Server-to-server communication is in fact one of the primary asset of the Jabber architecture.
Say I’m using Pidgin and that my Jabber Account is located on www.jabjab.de (it’s just one of the many public jabber servers), this will probably give me a JID (Jabber identifier) like [email protected]/home.
So suppose my JID is indeed [email protected]/home. The first part of the JID is “frank”, which identifies the NODE or, in other words, identifies a person. The second part of the JID is “jabjab.de” and it identifies the SERVER to call in order to send messages to “frank”. The last part of the JID is “/home” and it identifies the RESOURCE. Think of resources as “multiple identities”. Frank could in fact load 2 instances of Pidgin at the same time (one IM at home and the other at work) so it would result in two different JID, respectively “[email protected]/home” and “[email protected]/work”.
The XML messages : Streams and Stanzas
Like I said, Jabber messages are encoded in the XML format. A stream is a container to exchange information between a client and a server (e.g. between pidgin and jabjab.de). It simply is a XML element called “stream” that starts with <stream> and ends with </stream>. Within the stream element, both the client and the server can exchange other kind of XML messages (called stanzas). The communication is terminated when one of the 2 sides sends the closing </stream> element to the other. For example, if i close Pidgin, Pidgin will send the </stream> to jabjab.de and the session will be over.
One important thing to understand is that the stream DOES NOT exist between USER A and USER B… it exists between YOUR CLIENT (e.g. Pidgin) and the SERVER where YOUR Jabber account is located (e.g. jabjab.de).
Stanzas are special kind of XML messages that are sent within a stream element. The 3 most common stanzas are :
A message stanza is used when USER A ([email protected]/home) sends a message to USER B ([email protected]/home)… you know, like “Frank… are you there?”. it may looks like :
<message to=’[email protected]/home’>
<body>Frank… are you there?</body>
</stream> <!- – Well… the closing stream element is not there if the session is still active! Everything happens at real time after all – ->
Let’s take a second to think about what happens exactly when a message is sent between 2 entities from 2 different servers. USER A sends the message through his IM client. The message stanza will be sent to USER A server, which is someserver.com. someserver.com will see that the message is intended to USER B from someotherserver.com so it will send the message there. someotherserver.com will finally send the message stanza to USER B (considering that USER B and someotherserver.com have established a session together thru a stream element). Yay!
A presence stanza is sent when the status of a user changes (Idle, Offline, Available, Do not disturb, etc).
IQ (Info / Query) stanzas are more general purpose messages. It can be used when USER A wants to know something about USER B but that it cannot be achieved by sending a message or a presence stanza. For example, if USER A choose the “get info” option for USER B, an IQ stanza will be sent to USER B, and USER B will answer to USER A with another IQ stanza containing the information that USER A asked for.
That’s it for part 1… in the next part I think we’ll be ready to dive into XMPP4r. There is also one point that I didn’t address about XMPP… and this is the Authentication process (SASL or TLS). So, next part should talk about this as well.
21 thoughts on “IM Integration With XMPP4r”
This is a great intro to XMPP. I’ll be looking forward to seeing more about talking XMPP via ruby! I’ve setup jabber servers at a couple companies I’ve worked at, and I really dig modding apps to pester me via IM.
Thanks Frank! It’s a good one. I wasn’t even sure of how it worked even if I worked with you with TimmyOnTime. Shame on me.
I hope you will like the 2nd part as I should talk more about the XMPP4r! It will get more concrete. I didn’t installed any XMPP server yet and I was wondering if it was complicated to setup… that’s what I heard about it. I’d like to hear you on that.
Yeah, shame on me too because when I started trying out xmpp4r for TimmyOnTime, i had a rather unclear understanding of XMPP. I guess I was too excited to see Timmy replies to our commands to take the time learning the basics!
It depends a lot on the server. Jabberd 1.x wasn’t so bad to setup, but maintenance wasn’t super easy. Jabberd 2.x was just very awkward when I evaluated it. Ejabberd was really nifty from a scalability perspective, but there was no way I could get our IT staff (at the old co) to learn erlang to maintain it. Eventually, I settled on what became Openfire. It’s very easy to administer, but it’s a bit heavy on memory as far as what you’d expect a chat server to use. But as long as you have the RAM, it’s great; very easy and very full-featured.
And the timing couldn’t be better… I just started IM functionality that I promised my customer (foolishly, before I knew I could do it). It appears that the reliability of such a system depends entirely on the Jabber (OpenFilre, Ejabberd, etc.) server. For TOT id you run your own server, or use a public one?
Thanks for the info… that’s what I thought. So I guess my best bet would be to go with OpenFire? I don’t think that the high memory usage issue is so bad compared to the complexity of the other servers.
For ToT, we are currently using the Google chat servers (we use the “Google for your domain” service). We then asked our hoster to change our SRV records to have them point on Google servers. We are really happy with this setup so far… even if it makes us “depend” of Google (who doesn’t? 🙂 ). However, we might want to setup our own jabber server in the future.
A chinese version is here.thx~
Will you continue the series of article? I’m new to ruby and XMPP. Very glad that your blog was start for me.
Thanks for your support! I really want to continue to write on a consistant basis but as of late it has been very difficult to do. And yes, XMPP is the topic that I want to discuss the most. I plan to start writing about our XMPP integration in TimmyOnTime (company project).
Again, thanks for your support. I’ve been a very dead blogger since a while, But there is absolutely zero possibility of pulling the plug on RubyFleebie for the moment.
Продажа база досок объявлений для Xrumer и Allsubmitter.
База состоит из 31000 досок.
Обновлена ноябрь 2013.
подробнее тут – http://www.plati.ru/asp/pay.asp?idd=1619117
Late to this post. But was wondering if it is better to build such kind of event based system on Node.js rather than Ruby.
) furthermore share content using friends without worrying about leaving Google service they once put.
In 2009, Elmbrook School Zone in Brookfield, Wisconsin, banned teachers and students from using Facebook.
If a person want your online business to succeed at Facebook, think “community.
Best intro to xmpp