Error getting theme layout

Multi-Part Messages and AJAX (MAJAX? MXHR?)

Posted @ 1:15 pm by Grady Kuhnline | Category: Technology | 1 Comment

Digg has an article on their blog explaining their new MXHR technique for returning multi-part messages using AJAX. While their demos appear to be magical, the underlying technology is actually very similar to the existing COMET techniques. In a typical COMET application the browser creates an XHR connection and leaves it open until the server decides to send back some data. At the end of the request the connection is closed and the browser opens a second connection.

Digg’s MXHR Stream makes use of an oft-overlooked HTTP content type, “multipart/mixed.” Basically all the messages are sent over the same request with a delimiter marking the beginning of the next message. The main advantage being that for COMET to work, a series of connections needs to be closed and opened while MXHR can use a single connection. A basic message might look like this:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="|||"
--|||
Content-type: text/plain

This is message 1
--|||
Content-type: text/plain

This is message 2
--|||--

You can of course get clever with it, as Digg did, and pass back multiple mime types and handle each one differently. Combined with specific call-backs for each type, this method can be quite powerful.

var s = new DUI.Stream();
s.listen('text/html', function(payload) {
  $('#stream').append(payload);
});
s.listen('text/javascript', function(payload) {
  $('body').append('<script type="text/javascript">' + payload + '</script>' + payload + '');
});
s.listen('application/json', function(payload) {
  //do something with JSON
});
s.load('mixedstream.php');

The server might send back a file that looks like this:

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="|||"

--|||
Content-type: text/html

<p>This is message 1</p>
--|||
Content-type: text/javascript

alert('This is message 2');
--|||
Content-type: application/json

{"message":"This is message 3"}
--|||--

When looking over the spec for miltipart/mixed messages one can’t help but think, “holy crap! Bowsers can handle multipart messages?!?”  But the truth is that browsers don’t handle mixed messages. Digg’s MXHR is simply using a standard RFC message format and parsing it with JavaScript. It works like this:

  1. Make a request to a miltipart/mixed file using standard AJAX
  2. Listen for the readyState to change to “3″ which means “Downloading”
  3. At this point the responseText will contain part of the document
  4. Parse the responseText into the individual messages (see the processPacket() function) using JavaScript, splitting the message at the boundary.
  5. Set an interval at 15miliseconds and continue to read the responseText from the end of the last known messages and process the complete messages as they arrive.

While this initially looks to be some sort of undocumented browser magic, in reality it is a clever application of an existing message protocol and using JavaScript to parse a string. The implications are still pretty interesting; it isn’t hard to imagine making great use of this for complex AJAX applications or for enhancing a tool like google.load. Imagine using code like this to pull in all of your required libraries bundled into one request:

<script src="http://www.google.com/jsapi"></script>
<script>
  // this is fake code
  google.combine("jquery", "1.3.2");
  google.combine("jqueryui", "1.7.1");
  google.combine("swfobject", "2.1");
  google.loadCombined();
</script>

One thought on “Multi-Part Messages and AJAX (MAJAX? MXHR?)

  1. C. Blanquera says:

    Maybe a bundler that does:

    1. AJAX, for each packet received,
    2. Create script tag
    3. Add to script tag
    4. Append to body

    But heck why don’t we just eval the JS right when we get the packet (of course assuming we are getting the script locally). So this way it’s bundling on the fly, while streaming as received.

    Good post Grady.

Leave a reply

Error getting theme layout