Search

1/17/2011

Countdown to Knockout: Post 9 - WebSockets everywhere with Socket.io

17 Jan 08:25:28 - Initializing client with transport "xhr-multipart" (firefox 3.6.13)
17 Jan 08:25:28 - Client 39879375603049994 connected
17 Jan 08:25:33 - Initializing client with transport "websocket" (chrome 8.0.552.237)
17 Jan 08:25:33 - Client 9136935125570744 connected
17 Jan 08:25:46 - Answering flash policy request inline
17 Jan 08:28:01 - Initializing client with transport "htmlfile" (ie 6.0)
17 Jan 08:28:01 - Client 09895511576905847 connected


Countdown to Knockout: Post 9 - WebSockets everywhere with Socket.io

This is possible with at least two fairly well known techniques:

* XMLHttpRequest and the multipart/x-mixed-replace MIME type (which is enabled by setting multipart = true in the XMLHTTPRequest instance)

Although it was introduced by Netscape in 1995 (yes, when some of us were still unable to read properly), the only commonplace user agent to support it is Firefox.
* An <iframe> populated with a response with the headers Transfer-encoding: chunked and Connection: keep-alive.

The technique consists of writing <script> tags that call a function on the parent page as information becomes available to push to the client.

The disadvantage of this method is that it'll trigger a never-ending spinner or progress bar in most user agents, severely hurting the user experience. In Internet Explorer, this can be worked around by inserting the <iframe> in a hidden document (via the obscure ActiveX object htmlfile). This technique was exposed to me for the first time thanks to the Gmail Chat team. This gem was analyzed/discovered back in the day by Alex Russell.

By now, it's obvious that some lower-latency techniques are available to certain user agents, under certain conditions. The fundamental problem is that now the server has to treat HTTP requests differently, altering

* The headers sent with the response (Content-Type, Connection, etc).
* The duration (a timeout is required for long-polling, but not all the others)
* The "framing" of the messages. For multipart, each message has to be accompanied by a delimiter (boundary).
* Random quirks (IE requires a certain number of dummy bytes at the beginning of the document streamed through the iframe).


What else is burried down in the depth’s of Google’s amazing JavaScript?

// we were served from child.example.com but
// have already set document.domain to example.com
var currentDomain = "http://exmaple.com/";
var dataStreamUrl = currentDomain+"path/to/server.cgi";
var transferDoc = new ActiveXObject("htmlfile"); // !?!
// make sure it's really scriptable
transferDoc.open();
transferDoc.write("<html>");
transferDoc.write("<script>document.domain='"+currentDomain+"';</script>");
transferDoc.write("</html>");
transferDoc.close();
// set the iframe up to call the server for data
var ifrDiv = transferDoc.createElement("div");
transferDoc.appendChild(ifrDiv);
// start communicating
ifrDiv.innerHTML = "<iframe src='"+dataStreamUrl+"'></iframe>";

沒有留言: