With the summit coming up, I figured I'd write out what's been on my mind since
the previous summit regarding BOSH and XMPP's relevance in the web world.
These days, people building web apps expect to have sessions that persist
across tabs, and they expect to be able to use JSON. That's just the way web
development works. Browsers are becoming a lot smarter lately and maintain
more client state, but we're still not at the point where a multi-tabbed
website can have entirely local state on par with native clients.
BOSH is an awesome XMPP tunnel, but it's a poor "binding" of HTTP. It treats
HTTP like it's this awkward thing we have to navigate around rather than
recognizing that HTTP is not entirely terrible and REST generally makes good
sense.
IMO, the only interesting use of XMPP at the browser level is what was
proposed by Dave Cridland at the recent Realtime Conference. The browser
should be able to natively establish an XMPP session that is then shared
across tabs.
What I propose here is a new HTTP-based binding that simulates Dave's goal
with the help of a gateway (session stored on the server). A JavaScript API
should exist that can send/recv stanzas over some sharable XMPP session. If
the browser has native support, then the user himself would initiate the
connection using UI external to the HTML. If not, then we'll need some extra
API to initiate sessions that can be triggered from within the HTML.
It should also look good under the hood. One HTTP POST request to create a
session. Authentication provided using HTTP auth. Server responds with a
Cookie header that is used for all subsequent activity. HTTP POST to send a
stanza. HTTP GET (long-polling) to receive stanzas. No long-poll flip flopping
like BOSH.
To assist with sharing state across tabs, stanzas would be readable by all
tabs. No extra effort is needed to achieve this as long as all the long-polls
are requesting for data against the same checkpoints. The gateway would
persist received stanzas for a few minutes, for any number of browser tabs to
query against. To communicate across tabs, send data to yourself.
Content-neutrality. At the summit there was some talk about JSON<->XML
mappings. I'd argue that we don't necessarily need a mapping. We just need a
way to send JSON at all, untainted. Bear with me here. One of the great
features of HTTP is the ability to specify the content type. HTTP survived the
web world's transition from XML to JSON. The fact that XMPP baked-in its data
format was arguably very cool at the time of its origin, but it's not future
proof.
Imagine this:
<message from="alice" to="bob">
<content "urn:xmpp:altcontent" type="application/json">
lots of curlies
</content>
</message>
The idea here is to define a stanza in more abstract, as a set of simple
properties (from, to, type, id) and arbitrary content a la HTTP. If an
altcontent payload is not present, then the content is XML. If it is present,
then the content is anything else. There we go, universal transport without
changing XMPP's version number.
I'm not kidding:
<message from="alice" to="bob">
<content "urn:xmpp:altcontent" type="image/png" content-encoding="base64">
lots of printable chars
</content>
</message>
What this means is that a developer can write a webapp that speaks JSON
between two JIDs, using a very straightforward REST API. The JSON for a
message stanza from the perspective of the developer could look like:
{
"type": "message",
"from": "alice",
"to": "bob",
"content": {
...
}
}
Of course, if you try to communicate with an endpoint that doesn't understand
the JSON that you're sending, then it won't work. But that's the way of the
web. Different entities work with different types of content. We deal with it.
That all said, I do think we should define mappings for IM and pubsub
constructs so that they are ready to use from the web. Everything else stays
XML. If a web client wants to speak Jingle, for example, then it builds XML
like a man.
And yes, this could mean native clients needing to speak JSON to interact with
certain endpoints. This is how we evolve.
</three-am-brain-dump>
Justin