Jabber Boot Camp

Ralph Meijer & Peter Saint-Andre

Jabber Software Foundation

Agenda

Why Are You Here?

  1. You've heard that Jabber is a cool technology
  2. You want to write / improve a Jabber IM client
  3. You want to write / improve a Jabber server / component
  4. You want to add presence to an existing application
  5. You want to add real-time interaction to an existing application
  6. You want to solve Problem X in your project / company

What is Jabber?

Applications

History

Open Source Servers

==> Take control and run your own server!

Open Source Clients

Open Source Libraries

How Does it Work?

Privacy and Security

XML Streams

A Simple XML Stream (Part 1)

<stream xmlns='jabber:client' to='capulet.com' ...>

[authentication]

<iq from='juliet@capulet.com/balcony' type='get' id='foo'>
  <query xmlns='jabber:iq:roster'/>
</iq>

<iq to='juliet@capulet.com/balcony' type='result' id='foo'>
  <query xmlns='jabber:iq:roster'>
    <item jid='romeo@montague.net'/>
  </query>
</iq>

<presence/>

A Simple XML Stream (Part 2)

<message from='juliet@capulet.com' to='romeo@montague.net'>
  <body>Art thou not Romeo, and a Montague?</body>
</message>

<message from='romeo@montague.net' to='juliet@capulet.com'>
  <body>Neither, fair saint, if either thee dislike.</body>
</message>

<presence type='unavailable'/>

</stream>

Simple, But There Can Be Challenges

Coding a Simple Stream (xmpppy)

#!/usr/bin/env python
import xmpp

jid = xmpp.JID("juliet@capulet.com")
password = "R0m30"
toJid = "romeo@montague.net"
msgText = "Wherefore art thou?"

cl = xmpp.Client(jid.getDomain())
cl.connect()
cl.auth(jid.getNode(), password)
cl.sendInitPresence(requestRoster=1)
cl.send(xmpp.Message(toJid, msgText))
cl.disconnect()

Extending XMPP

Message Formatting

Chatrooms

Discovering Capabilities

User Info / Social Networking

How Do We Publish This Information?

PubSub Applications

Alternative Connection Methods

Structured Data Exchange

Collaboration

Jingle

An Atom over XMPP news ticker

Example entry

<entry xmlns='http://www.w3.org/2005/Atom'>
  <id>http://ralphm.net/#1</id>
  <title type='text'>Example entry</title>
  <summary type='text'>This is a sample entry</summary>
  <link href="http://mimir.ik.nu/"
           rel="alternate"
           type="text/html">
  <published>2006-08-18T16:37:00+00:00</published>
  <updated>2006-08-18T16:37:00+00:00</updated>
</entry>
import sys, feedparser, client
from twisted.internet import reactor

class Client(client.Client):
    logTraffic = False

    def initialization_failed(self, failure):
        print 'Initialization failed: %s' % failure

    def authenticated(self):
        self.xmlstream.send('<presence/>')
        self.xmlstream.addObserver('//message/event/items', self.onItems)

    def onItems(self, message):
        items = (e for e in message.event.items.elements()
                     if e.name == 'item' and e.entry)

        feed = '<atom xmlns="http://www.w3.org/2005/Atom">'
        for item in items:
            feed += item.entry.toXml().encode('utf-8')
        feed += '</atom>'

        parsed_feed = feedparser.parse(feed)

        for entry in parsed_feed.entries:
            print entry.title

Client(sys.argv[1], sys.argv[2]).connect()
reactor.run()

Further Resources

Conclusion