Two-Way Web: Can You Stream In Both Directions?

Update (couple of hrs later): I mailed Alex Russell (the guy who named Comet and knows plenty about it), it sounds like he’s been investigating this whole area and he’s sent me his views.

We know about Comet (AKA Push, HTTP Streaming) and its ability to keep streaming info from server to browser. How about streaming upwards, from browser to server, and preferably in the same connection? A reader mailed me this query:

Im missing one demo, would it be possible to reuse same stream in streaming demos to send msg to server, I’ve been digging throw your examples, but they all seem to create a new connection to the server when posting, would be very interesting see a demo that does this within the same stream, and of course the server code would be as interesting as the client.

Here’s my thinking, I’m sure a lot of smart readers will know more about this and I’ll be interested in your views – is it feasible? Any online demos?

Unfortunately, I’ve not seen anyone pull this off – it’s always assumed you need a “back channel”. It’s the kind of hack someone like Google or 37S would turn around and pull off even though it’s “obviously impossible” 😉 .

There are two key issues:

(1) Server needs to start outputting before incoming request is finished. With a specialised server, this problem could be overcome.

(2) (More serious as we can’t control the browser) The browser would need to upload data in a continuous stream. You can do it with Flash/Java, but I can’t see how to do this with standard JS/HTML. If you use XHR, you’re going to call send() and wave goodbye to the entire request…there’s no support for sequencing it. Same if you submit a regular form, change IFrame’s source etc. Even if you could somehow delay reading of content so it’s not immediately uploaded, the browser would probably end up not sending anything at all as it would be waiting to fill up a packet.

I think the solution lies in the Keep-Alive extension to HTTP 1.1:

What is Keep-Alive?

The Keep-Alive extension to HTTP, as defined by the HTTP/1.1 draft, allows persistent connections. These long-lived HTTP sessions allow multiple requests to be send over the same TCP connection, and in some cases have been shown to result in an almost 50% speedup in latency times for HTML documents with lots of images.

If you google for “xmlhttprequest keep-alive” or “ajax keep-alive”, you’ll see people talking about the idea a bit, but there’s not much info on how to script it for continuous connections and no demos to be found. It would make a great experiment if someone did a proof-of-concept!

As an alternative, you could consider a thin, invisible, Flash layer to handle transport, and degrade to frequent Submission Throttling where Flash isn’t an option.

<

p>BTW I have a post and podcast planned about the whole two-way web thing, which will be profound (the two-way web thing, not the podcast :-)). The web is entering a new era of Real-Time Collaboration and Communication, post-Ajax (and of course building on Ajax, just as Ajax builds on the technologies of the previous era: CGI, DHTML, CSS, etc).

Update: As mentioned above, Alex Russell mailed me his views. In particular, it’s interesting to consider the possibility that browsers might transparently exploit keep-alive if you hit the server frequently enough.

So I’ve spent some time investigating this (as you might expect), and at the end of the day there’s not much to be done aside from using Flash and their XMLSocket interface. That’s an obvious possibility given the high-performance Flash communication infrastructure we have in Dojo. Doing bi-directional HTTP probably won’t happen, though, but I don’t think that’s cause for despair. In my tests, we can get really good (relative) performance out of distinct HTTP requests so long as the content of the request is kept to a minimum and the server can process the connection fast enough. HTTP keepalive exists at a level somewhat below what’s currently exposed to browsers, so if the client and server support it, frequent requests through stock XHR objects may verywell be using it anyway. We’ll have to do some significant testing to determine what conjunctions of servers/clients might do this, however.

There are even more exotic approaches available from Flash peering that I’ve been investigating as well, but they will require significantly different infrastructure from what we already deploy that I think they’re still in the land of “hrm…someday”.

First we have to solve the *regular* Comet scalability problems for existing servers and app containers.

Regards

PS: we haven’t been making much noise about it, but serious work has started on an Open Source Comet protocol with initial implmemntations in both Perl and Python over at http://cometd.org. The initial client library is Dojo-based, but we’ll be publishing the protocol so that anyone can “play” with it.

6 thoughts on Two-Way Web: Can You Stream In Both Directions?

  1. I agree that the solution will currently have to be the Flash XMLSocket object. Keep in mind that:

    1) it’s only available in the latest Flash incarnations

    2) cross-site permissions are dealt with via the crossdomain.xml overrride file

    3) as Brendan Eich said at AE in May, as a plugin Flash will always be a second-class citizen in the browser heirarchy. The implication is that the plugin is subject to the mercy of the single-threaded scripting environment and other limitations of its confines.

  2. I’ve created a Ruby on Rails plugin called Juggernaut that initiates a flash xmlsocket between server and browser allowing real time communication between the two. This opens the door to all sorts of functionality such as chats and collaborative wikis/cms. The open socket connection allows the server to ‘push’ base64 encoded javascript to the browser which is subsequently decoded and evaluated. Juggernaut uses Flash version 6 which is supported by more than 95% of users – so Brent, it’s not only available in the latest Flash incarnations. Also – RE crossdomain.xml – you’ll find a xmlsocket implementation much easier than a comet one. The restrictions on a xmlsocket are such that a socket connection can only be made to the same domain – or subdomain. XHR requests, on the other hand, can only (I think) make a request to exactly the same address – bar some Iframe hacks. This adds another layer of complexity to a comet server and requires, in Rails at least, a custom dispatch servlet. Flash doesn’t have this problem. The other obvious advantage a Flash xmlsocket has over Comet is that it doesn’t crash your browser. Browsers weren’t designed for long lived http connections and some struggle under Comet connections. I’m going to release it in the next week or so. The website (not finished yet) will be here. More information about Juggernaut is available here. If you’d like to beta test the plugin – do get in touch.

  3. It’s easier to do if you control the server side. For example, in Tomcat, it’s fairly trivial to keep the socket open (and put it in a Map for future use). I’ve used this approach for at least 8 years, with various clients (small java applet, flash xml client, etc). There’s no problem keeping the socket open for several hours in most cases.

  4. The problem is not on server side Gordon but on client side! Proxy, firewall, router ….

    It’s impossible to have a 100% cross client configuration solution (expect dirty poll ;-)).

    And Adobe restricts the security for every Flash version, now if you want use XMLSocket even in the same server, the XMLSocket server MUST send the cross-domain XML piece at the first, then the client is unconnected and reconnect again. And I have the feeling with Flash 10 will be harder…

Leave a Reply