XMPP-FTW


Lloyd Watkin
Email/JID: lloyd@evilprofessor.co.uk ::: @lloydwatkin

;;;;;;;;;;;;;;;;;;;;;;;;;;;

Me

Lloyd Watkin


@lloydwatkin

http://evilprofessor.co.uk

lloydwatkin on github ...and most other places

Work for Surevine


Organise world record breaking event Scuba Santas

Member of the XSF

PinItTo.me - realtime, infinite, open source, virtual corkboard (https://go.pinitto.me)

buddycloud - open source/standards, XMPP-based federated social network

I like open source stuff

What is XMPP?


eXtensible Messaging and Presence Protocol
(aka Jabber)


Started around 1998
Became part of IETF in 2002


http://xmpp.org


Think you don't use XMPP?


Google Hangouts (talk)
Facebook Chat
Android Intents
Whatsapp
Zoosk


Internet of things

Utility companies

Gaming applications

Social networks


Many, many more places which don't advertise its usage...

What is it?

Came about in an era of closed protocol chat systems:

AIM, ICQ, Yahoo! Messenger, etc


  • Designed to be like the web
  • Open standard
  • Federated
  • Secure
  • Scalable (messages are pushed)
  • Decentralised
  • Asynchronous
  • Community
  • Proven (14 years old)

Where XMPP wins

At its core very simple set of functionality:

IM and Presence


The 'X' is what makes XMPP such a a great system:

  • Multi-user chat [XEP-0045]
  • Publish-Subscribe [XEP-0060]
  • Jingle (P2P media sessions) [XEP-0166]


http://xmpp.org/xmpp-protocols/xmpp-extensions/


People also build their own or overload existing standards e.g.

  • buddycloud
  • Chesspark (uses MUC as a data transport)

Concepts

JID: Your unique identifier on the network


lloyd@ evilprofessor.co.uk/ southville-js


  • lloyd: Username
  • evilprofessor.co.uk: Domain
  • southville-js: Resource


A user can be logged in from multiple resources at once (phone, desktop, laptop, tablet, etc).

Each can have a priority which helps route messages to the appropriate device.

XMPP Base Messages

Messages:


      <message from="lloyd@evilprofessor.co.uk/boat-house"  
            to="megan@evilprofessor.co.uk/home" type="chat">
          <body>I'm giving my talk at JS workshop</body>
      </message>
      

Presence:


      <presence type="dnd">
          <status>Giving a talk....</status>
          <priority>-1<priority>
      </presence>
      

IQ:


      <iq from="lloyd@evilprofessor.co.uk/southville-js" id="1">
         <query xmlns="jabber:iq:roster" />
      </iq>
      

XMPP in the browser

Most popular project is strophe.js


Connects to XMPP server using BOSH (long polling).

Websocket extension for XMPP being finalised


But...


Still requires handling of XML

Browser is all about JSON: quick, simple, fast

Web developers want minimal APIs and fast implementation

XMPP-FTW

Server side library which allows users to interact with XMPP over a websocket using JSON


https://xmpp-ftw.jit.su

https://github.com/lloydwatkin/xmpp-ftw


  • xmpp-ftw
  • xmpp-ftw-demo
  • xmpp-ftw-avatar
  • xmpp-ftw-buddycloud
  • xmpp-ftw-disco
  • xmpp-ftw-item-parser
  • xmpp-ftw-muc
  • xmpp-ftw-pubsub
  • xmpp-ftw-register
  • xmpp-ftw-superfeedr

Messaging


Sending a message


        socket.emit(
            'xmpp.chat.message',
            {
                "to": "other@evilprofessor.co.uk",
                "content": "Hello world"
            }
        )
        

Receiving a message


        socket.on('xmpp.chat.message', function(data) {
            console.log(data)
        })

        /*
        {
            from: {
                domain: 'evilprofessor.co.uk',
                user: 'world'
            },
            content: 'Hello people!',
            format: 'plain'
        }
         */
        

Presence


Sending presence information


        socket.emit(
            'xmpp.presence',
            {
                "show": "online",
                "status": "I'm using xmpp-ftw!",
                "priority": 10,
             /* "to": "megan@evilprofessor.co.uk/mobile" */
            }
        )
        

Receiving presence data


        socket.on('xmpp.presence', function(data) { 
            console.log(data); 
            /*
             * { 
             *   from: { domain: 'evilprofessor.co.uk', user: 'lloyd'},
             *   show: 'away',
             *   status: "I'm going away",
             *   priority: 10
             * }
             * ...each of these are optional...
             */
        })
        

Your turn!



Some basics, then we'll start playing with XMPP

Lets get connected...



<script type="text/javascript" src="{ MY_IP_ADDRESS+PORT }/scripts/primus.js"></script>
<script type="text/javascript">
    var socket = new Primus('http://' + { MY_IP_ADDRESS+PORT })

    socket.on('error', function(error) { console.log(error) })

    socket.on('open', function(data) {
        console.log('Connected')
        // Now do stuff!
    })
</script>
        

You'll need to serve this via HTTP. If you don't have something set up use your code from Jack's talk this morning.

Authentication


    socket.emit(
         'xmpp.login',
         { 
             "jid": "test@example.com",
             "password": "password",
             "host": "localhost"
         }
        )
    

'localhost' as we're faking a local server domain.

...then listen for authentication event...


    socket.on('xmpp.connection', function(data) { 
        console.log(data)
        /*
         * 'online'
         */
    })
    

Lets do some things...


Set up a couple of basic listeners:


    socket.on('xmpp.client.error', console.error)
    

Step #1: Rude not to say hello:


    socket.emit(
      'xmpp.presence',
      { status: 'Trying out XMPP!', priority: 10, show: 'online' }
    )
    

This now means that the server knows to send any packets your way

Get to know each other...

Get the JIDs of the people next to you and lets send them some messages...


Listen for messages:


    socket.on(
      'xmpp.chat.message', 
      function(data) { console.log(data) }
    )
    

Send a message:


    socket.emit(
      'xmpp.chat.message',
      {
          to: { person } + '@example.com',
          content: 'How much longer? Yawn!'
      }
    )
    

Presence


In order to view another user's presence you must first subscribe:


    socket.emit('xmpp.presence.subscribe', { "to": "user@evilprofessor.co.uk" })
    

User receives:


    socket.on('xmpp.presence.subscribe', function(data) {
            console.log(data)
    })
    

If we want to subscribe them we reply:


    socket.emit('xmpp.presence.subscribed', { "to": "user@evilprofessor.co.uk" })
    

Subscriptions are one way you'll need to subscribe back

Presence


Sending presence information


    socket.emit(
        'xmpp.presence',
        {
            "show": "online",
            "status": "I'm using xmpp-ftw!",
            "priority": 10,
         /* "to": "megan@evilprofessor.co.uk/mobile" */
        }
    )
    

Receiving presence data


    socket.on('xmpp.presence', function(data) { 
        console.log(data); 
        /*
         * { 
         *   from: { domain: 'evilprofessor.co.uk', user: 'lloyd'},
         *   show: 'away',
         *   status: "I'm going away",
         *   priority: 10
         * }
         * ...each of these are optional...
         */
    })
    

Publish Subscribe



Lets look at the realtime message wall

There's lots more...

  • DISCO: Discover server features and items
  • MUC: Multi user chat
  • Roster: address book
  • XML RPC: run remote commands
  • Jingle: Multimedia sessions (webcam, files, voice, webRTC)


There's over 300 XEPs at http://xmpp.org/xmpp-protocols/xmpp-extensions/



Anything you can hold in XML can potentially become a XEP, or you can use existing stanzas

Continue playing...

https://xmpp-ftw.jit.su

Manual

https://xmpp-ftw.jit.su/manual
Presents all of the incoming/outgoing messages with example payloads

Demo Client

Purely javascript
Parses the manual and hooks on to incoming messages and gives autocomplete (with example payload) for outgoing messages
https://xmpp-ftw.jit.su/demo

Feel free to ask questions or get in touch later!