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.

Portable Comet? It’s the IFrame, Stupid!

Comet Takes to IE Like a Fish Takes to Acid

Comet – or HTTP Streaming, if you will – is a little sensitive when it comes to portability, and I’ll give you four guesses which major browser is causing the grief? Yeah, IE makes it difficult for two reasons: (a) IE’s XMLHttpRequest component doesn’t tell you anything about the response until the connection has closed – even if you try polling it instead of relying on onReadyStateChange, you’ll still get an empty string (Try it); (B) Okay, switch to plan B and inspect IFrame content – we can’t rely on onload, which is only called once at the end, so we must poll. But no, polling won’t help either, as the IFrame content remains empty until (you guessed it) the connection is closed. (Try it).

We’re Going Back, Way Back: Inline Script Tags

Don’t give up on the IFrame so fast … we’re closer than we think. Actually, the solution harkens back to one of the original Push techniques: outputting script tags with inline code (what the HTTP Streaming pattern calls “page streaming”). If you do that in your main document, the code will be executed immediately, and the same is true if you do that inside an IFrame.

I’m talking about a service that outputs stuff like this:

  1. <script type="text/javascript">
  2.     doSomething();
  3. </script>

So Make the Server Spit Out Inline Script Tags

The portable solution is this: Have the server continuously output script tags that call a known function in the parent frame. When you set the child IFrame’s source to point to this service, it will start evaluating the inline scripts as they pop out of the server. This happens to be one technique people have used for remoting for many years (I think Brent Ashley recently told me he was doing it in ?1999). The twist with Comet is that you keep doing it, and don’t actually close the connection for a while. (Again, I’m sure some people were doing that for a long time too!).

Is it elegant? No. It means the remote service is suddenly coupled to the client-side of the web app – it has to know something about what’s in the parent frame, whereas you’d often like it to be generic and just deliver a response in XML, JSON or whatever. Like most things Ajax, we’re using a hack because it nonetheless push all the right buttons for our users.

Try It. Portable Comet for the Masses

Here’s Some Code I Prepared Earlier

In the example above, the remote service outputs script tags in a loop – it’s a simple countdown service:

  1. <?
  2.   for ($i=$_GET&#91;"start"]; $i>=0; $i--) {
  3. ?>
  4.   <script type="text/javascript">
  5.     window.parent.onNewValue(<?= $i ?>);
  6.   </script>
  7. <?
  8.   }
  9. ?>

And in the browser’s initial Javascript, there’s a run-of-the-mill onNewValue() function, it looks something like this.

javascript

  1. function onNewValue(i) {
  2.   statusDiv.innerHTML = i; // Paint the new value onto the page
  3. }

See what I mean about coupling? The server-side service had to know that there’s a Javascript function defined in the parent called onNewValue(). At least we’ve minimised the coupling by using an Observer/Event style indirection approach – evidenced by the simple call to “onNewValue()”. It would be worse if it was the script that actually performed application logic directly, repainting the DOM with the new value.

IFrame is the new XMLHttpRequest

Whoever put the X in Ajax ought to put an I in Comit. IE’s XHR component doesn’t provide the response until the connection has closed, and I don’t think version 7 changes that. Assuming (graciously) it happens in IE8, you’ll need to use IFrame for the next five years if you’re doing any Comet work. And of course, you won’t need to do that, because libraries will do it for you.

BTW You could argue that IE is doing the right thing by preventing access to the content until the connection is closed. Maybe they are, maybe they aren’t. From a pragmatic perspective, though, portable Comet requires Ajax. Alternatively, use IFrame with IE and XmlHttpRequest with the others, though I’m not sure if there’s much mileage to be gained from this hybrid strategy.

Comet: It’s Ajax for “Push” (Podcast)

Here’s a podcast about Comet – exploring the two-way web with Ajax. From my Ajaxian post earlier today:

Alex Russell has coined a term for a flavour of Ajax that’s been getting more attention of late. Comet describes applications where the server keeps pushing – or streaming – data to the client, instead of having the browser keep polling the server for fresh content. Alex identifies several buzzworthy examples:

This is an important article because it captures a growing trend in Ajax, a trend I had in mind when I said we expect to hear more about “Push and the Two-Way Web” in the next twelve months, on the occasion of Ajax’s birthday. There will, of course, be people saying “there’s nothing new here”, and that’s presumably all too obvious to Alex himself, who has worked with these ideas for a long time. But as with Ajax, it’s the power of a name. I don’t think these ideas can adequately be described as Ajax, because Ajax changes a lot about the browser whereas Comet fundamentally changes the nature of browser-server communication. I see Comet as part of the overall Ajax trend, complementary to the UI aspects of Ajax.

People may also say there are existing names like “Push”. True, but they have baggage – I think it’s useful to have a name for this architectural pattern in light of the relationship to Ajax.

Anyways, I wanted to expand on some of the thoughts in the article and after the recent Basics of Ajax Podcast, I’m in the mood for more audio rambling. So here’s a 56-minute discussion about Comet and the general trend of push and streaming within Ajax.

Click to download the Podcast. You can also subscribe to the
feed if you want future podcasts automatically downloaded - check out the
podcast FAQ at http://podca.st.

Shownotes…

It's the Duplex, Stupid! Push or Pull - it doesn't matter so much. What's critical here is the focus on the two-way web.

Applications - Chat - Wiki - News - Current events, sport, financials, etc - Trading and Auctions - Real-time control and logistics - File transfer (combine with local storage) - Any other genre you'd care to name

Vanilla Ajax: Await the User

Comet Ajax: Keep Pushing

Polling Ajax: Keep Pulling

Benefits of Comet - Responsive: data pumped out immediately - More stable profile - Less overhead of establishing connections

Benefits of Polling - Browser memory - Can run on any standard server; Comet requires suitable server - Can upload at the same time - Can run on - with Comet, XHR and IFrame won't always reflect changes while the connection's open - Being more standard, works with existing infrastructure. Comet is vulnerable to middle-men dropping the connection. - Simpler architecture - only the browser's in control - Easier to test - More familiar architecture - Less programming effort - with Comet, must watch for changes on the stream - More efficient for infrequently accessed data - Leverages caching

Maybe Comet causes more pain, but if it keeps the user happy ...

Questions and Trends - Which to use. Variables include: frequency of updates, importance of updates, server capabilities, target browsers - Dealing with incoming messages, e.g. Distributed Events pattern, Event bus (browser or server?), etc - Workarounds for throbber, status bar, clicking sound, etc. - How often to drop connections - How browsers can accommodate it

Proof-Of-Concept Demos - Wiki using Periodic Refresh/Polling - Wiki using HTTP Streauh, Comet (Actually, this is only a very basi implementation - there's no use of events, just custom handling of HTTP.

Related Patterns - HTTP Streaming - Periodic Refresh (aka Polling) - Distributed Events

As always, feedback is welcome – [email protected]

SAG Ajax Patterns Review 1 – XHR Call, IFrame Call, HTTP Streaming

A little while back, I mentioned that some people in the patterns community have been noticing the Ajax Patterns. In particular, there have been a series of discussions about the patterns by the Software Architecture Group in the University of Illinois Computer Science Dept (home of Netscape forerunner Mosaic btw). The SAG is led by Ralph Johnson (Gang Of Four “Design Patterns” author) and the group also includes Brian Foote, who blogged about Ajax as a pattern earlier on and has kindly been keeping me updated on the MP3s emerging from these discussions.

The feedback has been very helpful and I’ve been able to incorporate it in time for the physical publication – thanks again to everyone in the group.

While listening to the audio, I’ve been taking notes and writing some comments. With the permission of Ralph and Brian, I’m going to be posting these, each discussion as a separate post. It’s an opportunity to see how a group of very intelligent people without much Ajax experience respond to Ajax and the Ajax patterns. You’ll notice two conventions here: “TODO” is a note to myself that some action needs to be taken. “MM” signals my ideas, views, and comments back to the group.

Jan-30-2006 First Ajax Patterns Discussion

30/1/2006 Ajax Workshop

9:45 XMLHttpRequest Call

What it's about. - Probably missing in old browsers if you can't use Ajax on them. - Remote call to server without refreshing a whole page. - I assumed in JS you can open a socket, you could have done this yourself. - Depends on what the browser provides. But not cross-browser. [TODO Mention HTTP restriction and what JS can do, cf Richer Plugin] - Ironically, because JS isn't general-purpose (due to security), it's wound up being a better citizen. Also because it was kind of low-brow, everyone kind of ignored it. - The big idea is this is a way to call the server.

Interesting characteristic of XHR: - Asynchronous - Built-in security (originating server)

Did you find this pattern easy to understand? - One thing that troubles me (not particular to this pattern), pretty soon the code becomes spaghetti-like. Nd good patterns on how to manage code. [MM Agree, we need a JS patterns book! That's not the aim here, the book will make that explicit]. - Part of the problem here is JS itself. - Haven't seen the word "simple" "elegant" or "pretty" to describe JS architect. This is a Rube Goldberg solution, duct-tape ... at it's best. [MM Sort of true, but there's a lot that can be done to improve it] - There are libraries that help. (AjaxCaller, Prototype).

Writing here, even though it doesn't address these problems, could understand/follow it? - I don't like the Problems section. "How can the browser communicate with the server?" But this pattern is more specific than server communication. The next 1-2 patterns have the same problem. - But the problem might be the same, but different Solution. What I dislike is the forces are also the same. How does it mitigate the forces? Maybe there should be some different forces. - Only difference between IFrame and XHR is only restricted to same host, so maybe okay other than that. [MM Actually, even this difference doesn't exist, since you can't read a remote IFrame's content] [TODO Possibly update forces to be different, back-reflect the solution]

22:30 Doesn't say anything about being asynchronous at the start - Ajax should be highly responsive. Distributed system, so you want to minimise communications. ie Must be asynchronous [TODO Revise forces. HOWEVER, note that XHR doesn't have to be async.] - "Conventional means ... slow." He's trying to rule out Solutions, before we get to the solution. [MM This sort of goes against the previous suggestion that IFrame and XHR need different Forces. Maybe suggests different people have different views on this issue of the forces.] Doesn't so much talk about the forces as take potshots at existing solutions. [MM This is a fair point, more prevalent in the initial patterns as they're arising as a reaction to conventional web dev, but it's true you don't have to formulate them that way.]

26:30 It's a long pattern, is that okay? - Yes, longer than all the others, problem if all patterns were this long, but given it's so core to Ajax, it's fine. - Length is fine, but a lot of code there. - I would like more examples of the old way of doing things. [Covered in the Anagrams tutorial, perhaps reference it] - The general idea is if you have a big object and only small things change at a time, then you keep going back to the server and grabbing small bits of it. I think of Google Maps. - Pattern could be shorter if PHP wasn't written. - So you'd like less example code, others want more. - It's a Chimera/Frankenstein ie PHP (or whatever serverside) on the one side, and even JS is a kind of Frankenstein language. So it's important to have the PHP, reminds me that's the game I'm playing. I didn't mind it, seeing all the pieces together reminds you we're receiving small chunks etc. - The pattern is really introducing XHR, not how to use it. - Disagree with people who are trying to call everything a pattern. - Well, these particular patterns are what he calls foundational. He says they're not really patterns, they're just how the technology works. - I know what you're saying about that, and it bugs me too, but I've been trying to come up with a rationalisation for admitting that this kind of design exposition is a contribution to our software architecture literature ... and if designs recur, if a lot of people come up with the same solution to a problem ... my mind cries out to keep distinct from Visitor and ... Composite, but I don't have the vocab to keep them distinct, and I want to maintain this notion that the patterns community is talking about good ideas that keep coming up over and over that we haven't come up with ourselves ... true, it's a different kind of discussion from the GoF, without having disclaimer kind of nags at me [MM Agree wholeheartedly, why I've sounded a bit apologetic describing these as patterns, but they just fit into the overall language well. See earlier blog post.] [TODO Needs better "disclaimer" in the book] - So then what are the patterns around XHR? - Event handling, Asynchronous call - Lots of people dealing with SOA, problems s.a. async smell the same but with different names [MM Later patterns, e.g. Distr'd events] - Error detection - Invesion-of-control/DepInj/Observers. People patternising closures. There's an aspect of dealing with callbacks. Callbacks are part of the discussion here, and that's an idea that comes up here. - Feedback from the call. Or using poll. Fire-and-forget. Typical remote invocation styles: What does XHR do? - In JS: Callbacks used here (XHR), also used for user interops. We want to follow flow-of-control, but if everything is event handlers, hard to follow. (ie JS hard to follow because of this style.) A lot of the time, "callbacks" are basically continuations. It's a general pattern discussion we could have.

41:30 Real-World Examples and Code. - These systems are not thoroughly responsive as claimed. Google Suggest surprisingly fast. Others like Backpackit and Kiko not. [MM See perf optimisation, also comments in HTML Message, etc. Alex Kirk mentioned Kiko a while ago as a problem due to too much browser-side rendering.] - Need to avoid too many requests - Curious didn't mention the most famous examples (Google Suggest etc) Maybe can't see the code. But it's JS, have to be able to. But maybe unclear. [MM Yes, obfuscated. Also, tried to avoid the cliche references too much, they're mentioned elsewhere] - Discussion about mint stats package, security issues in uploading data. - Next, ways of telling your web browser what to report back. - If trying to keep people from attacking you. It's interesting to me. - Applets got crucified for some of the security problems that JS has. People moved on from panicking about them, but got away with it because browser wars finished etc.

=============================================================== 49:00 IFrame Call - Poor Man's version of the previous one. - More like a hack - What can you do with one that you can't do with the other? XHR and not with IFr? - I only know the other way round...IFrame is more compat with older browsers. - Long discussion about relative benefits etc. - Comment about Google using IFrame. Not sure if it's true as you can zoom in.[TODO More specific about how it's being used. (I think book version already does that)] - IFrame Call doesn't talk about hidden frames. [MM XHR Pattern alternatives has a detailed comparison)] [TODO XHR comparison should briefly explain how the two are diff, not just compare the benefits] - IFrame has no timeout function. (But could fake this using polling) - Calls IFrame a hack ... Pot calling the kettle black, since Ajax itself is sort of a hack. Is it bad just because it's old? [MM Again, comes down to the comparison. XHR is a more intention-based, intuitive, API, although it's true that you won't care about that because you should use a wrapper lib anyway. Better argument is the extra functionality such as call tracking.] - Would like better explanation on what's so bad about IFrames. [TODO Include x-reference in IFrame Solution. Also mention the portable wrappers in the Solution, ie you shouldn't actually care/know which you're using is the more pertinent issue here.] - I'm feeling historical. The room we used to sit in is the room where the original Mosaic web browser developers sat. Continuously astonished in the web industry, using things that in ways they weren't invented for. Go down this list, frames, tables ... Ungodly mess, but really impressed, poster child for pragmatism and "worse is better". IFrame is a typical example. - I didn't get any feel on whether I would use one or the other. - Intrigued by the history of JS. Knowing that IFrame predated XHR because features that made it easier to do the second came along in 2003. Whether it needs to be here, not sure. [TODO Sidebar?]

=============================================================== 49:00 HTTP Streaming

Is it competition for the other two?  
  - Different problem (push/streaming)
  - "How can the browser communicate with the server?" Same
    problem as the other two.
    - I don't know, it turns the table. Little pattern device
      of using the same problem with different solutions may
      be okay here. Here, the forces would be different.
      Could make the case for having the same problem.  [TODO
      Change the problem statement, just enough to make it a
      little different from previous two.]

What would make you choose this over the others?
  - Changes coming from lots of other sources, not just the
    client.
  - e.g. Chat system.
  - I don't want to do this. Don't want to grow the system
    ...
    - But scaleability is oversold. You'll never be like
      EBay, don't need to scale up like that.  [TODO Good
      point, mention in the pattern.]
    - Our wiki - 4-5 hits per second - can handle that, but
      not scaleable.  Wikipedia is not a wiki in that sense,
      pages don't change because I believe something like 90%
      of all edits are done by 200 people, these are official
      wikipedia authors. Specific process.
    - Doesn't fit into proxies. Caching etc doesn't ddeal
      with longer responses.

Long refactoring illustration here. Do the others have one?
  - Streaming wiki demo.
  - Seemed nice to refactor in this way.
  - The group is looking at the live version on the web -
    "There's about a half dozen laptops in it for the
    author's information". It worked.  [MM Phew]

=============================================================== 1:20 - I didn't get the feel of which one to use. - Was hidden in the Alternatives section [MM TODO Emphasise this in the partintro, maybe in the solutions]

====== Next time: Different patterns - Problem with web version [MM Incidentally, the wiki publishing hasn't worked out ideally, didn't get the full benefit as I didn't open up the wiki (and still haven't due to spam). Ideally would have better PS format. (Blogged about printing from the web a yr ago as it happens.)] - Being on the web doesn't seem to affect (ie drop) sales. [MM We'll soon find out...:-)]

SAG Ajax Patterns Review 1 – XHR Call, IFrame Call, HTTP Streaming

A little while back, I mentioned that some people in the patterns community have been noticing the Ajax Patterns. In particular, there have been a series of discussions about the patterns by the Software Architecture Group in the University of Illinois Computer Science Dept (home of Netscape forerunner Mosaic btw). The SAG is led by Ralph Johnson (Gang Of Four “Design Patterns” author) and the group also includes Brian Foote, who blogged about Ajax as a pattern earlier on and has kindly been keeping me updated on the MP3s emerging from these discussions.

The feedback has been very helpful and I’ve been able to incorporate it in time for the physical publication – thanks again to everyone in the group.

While listening to the audio, I’ve been taking notes and writing some comments. With the permission of Ralph and Brian, I’m going to be posting these, each discussion as a separate post. It’s an opportunity to see how a group of very intelligent people without much Ajax experience respond to Ajax and the Ajax patterns. You’ll notice two conventions here: “TODO” is a note to myself that some action needs to be taken. “MM” signals my ideas, views, and comments back to the group.

Jan-30-2006 First Ajax Patterns Discussion

30/1/2006 Ajax Workshop

9:45 XMLHttpRequest Call

What it's about. - Probably missing in old browsers if you can't use Ajax on them. - Remote call to server without refreshing a whole page. - I assumed in JS you can open a socket, you could have done this yourself. - Depends on what the browser provides. But not cross-browser. [TODO Mention HTTP restriction and what JS can do, cf Richer Plugin] - Ironically, because JS isn't general-purpose (due to security), it's wound up being a better citizen. Also because it was kind of low-brow, everyone kind of ignored it. - The big idea is this is a way to call the server.

Interesting characteristic of XHR: - Asynchronous - Built-in security (originating server)

Did you find this pattern easy to understand? - One thing that troubles me (not particular to this pattern), pretty soon the code becomes spaghetti-like. Nd good patterns on how to manage code. [MM Agree, we need a JS patterns book! That's not the aim here, the book will make that explicit]. - Part of the problem here is JS itself. - Haven't seen the word "simple" "elegant" or "pretty" to describe JS architect. This is a Rube Goldberg solution, duct-tape ... at it's best. [MM Sort of true, but there's a lot that can be done to improve it] - There are libraries that help. (AjaxCaller, Prototype).

Writing here, even though it doesn't address these problems, could understand/follow it? - I don't like the Problems section. "How can the browser communicate with the server?" But this pattern is more specific than server communication. The next 1-2 patterns have the same problem. - But the problem might be the same, but different Solution. What I dislike is the forces are also the same. How does it mitigate the forces? Maybe there should be some different forces. - Only difference between IFrame and XHR is only restricted to same host, so maybe okay other than that. [MM Actually, even this difference doesn't exist, since you can't read a remote IFrame's content] [TODO Possibly update forces to be different, back-reflect the solution]

22:30 Doesn't say anything about being asynchronous at the start - Ajax should be highly responsive. Distributed system, so you want to minimise communications. ie Must be asynchronous [TODO Revise forces. HOWEVER, note that XHR doesn't have to be async.] - "Conventional means ... slow." He's trying to rule out Solutions, before we get to the solution. [MM This sort of goes against the previous suggestion that IFrame and XHR need different Forces. Maybe suggests different people have different views on this issue of the forces.] Doesn't so much talk about the forces as take potshots at existing solutions. [MM This is a fair point, more prevalent in the initial patterns as they're arising as a reaction to conventional web dev, but it's true you don't have to formulate them that way.]

26:30 It's a long pattern, is that okay? - Yes, longer than all the others, problem if all patterns were this long, but given it's so core to Ajax, it's fine. - Length is fine, but a lot of code there. - I would like more examples of the old way of doing things. [Covered in the Anagrams tutorial, perhaps reference it] - The general idea is if you have a big object and only small things change at a time, then you keep going back to the server and grabbing small bits of it. I think of Google Maps. - Pattern could be shorter if PHP wasn't written. - So you'd like less example code, others want more. - It's a Chimera/Frankenstein ie PHP (or whatever serverside) on the one side, and even JS is a kind of Frankenstein language. So it's important to have the PHP, reminds me that's the game I'm playing. I didn't mind it, seeing all the pieces together reminds you we're receiving small chunks etc. - The pattern is really introducing XHR, not how to use it. - Disagree with people who are trying to call everything a pattern. - Well, these particular patterns are what he calls foundational. He says they're not really patterns, they're just how the technology works. - I know what you're saying about that, and it bugs me too, but I've been trying to come up with a rationalisation for admitting that this kind of design exposition is a contribution to our software architecture literature ... and if designs recur, if a lot of people come up with the same solution to a problem ... my mind cries out to keep distinct from Visitor and ... Composite, but I don't have the vocab to keep them distinct, and I want to maintain this notion that the patterns community is talking about good ideas that keep coming up over and over that we haven't come up with ourselves ... true, it's a different kind of discussion from the GoF, without having disclaimer kind of nags at me [MM Agree wholeheartedly, why I've sounded a bit apologetic describing these as patterns, but they just fit into the overall language well. See earlier blog post.] [TODO Needs better "disclaimer" in the book] - So then what are the patterns around XHR? - Event handling, Asynchronous call - Lots of people dealing with SOA, problems s.a. async smell the same but with different names [MM Later patterns, e.g. Distr'd events] - Error detection - Invesion-of-control/DepInj/Observers. People patternising closures. There's an aspect of dealing with callbacks. Callbacks are part of the discussion here, and that's an idea that comes up here. - Feedback from the call. Or using poll. Fire-and-forget. Typical remote invocation styles: What does XHR do? - In JS: Callbacks used here (XHR), also used for user interops. We want to follow flow-of-control, but if everything is event handlers, hard to follow. (ie JS hard to follow because of this style.) A lot of the time, "callbacks" are basically continuations. It's a general pattern discussion we could have.

41:30 Real-World Examples and Code. - These systems are not thoroughly responsive as claimed. Google Suggest surprisingly fast. Others like Backpackit and Kiko not. [MM See perf optimisation, also comments in HTML Message, etc. Alex Kirk mentioned Kiko a while ago as a problem due to too much browser-side rendering.] - Need to avoid too many requests - Curious didn't mention the most famous examples (Google Suggest etc) Maybe can't see the code. But it's JS, have to be able to. But maybe unclear. [MM Yes, obfuscated. Also, tried to avoid the cliche references too much, they're mentioned elsewhere] - Discussion about mint stats package, security issues in uploading data. - Next, ways of telling your web browser what to report back. - If trying to keep people from attacking you. It's interesting to me. - Applets got crucified for some of the security problems that JS has. People moved on from panicking about them, but got away with it because browser wars finished etc.

=============================================================== 49:00 IFrame Call - Poor Man's version of the previous one. - More like a hack - What can you do with one that you can't do with the other? XHR and not with IFr? - I only know the other way round...IFrame is more compat with older browsers. - Long discussion about relative benefits etc. - Comment about Google using IFrame. Not sure if it's true as you can zoom in.[TODO More specific about how it's being used. (I think book version already does that)] - IFrame Call doesn't talk about hidden frames. [MM XHR Pattern alternatives has a detailed comparison)] [TODO XHR comparison should briefly explain how the two are diff, not just compare the benefits] - IFrame has no timeout function. (But could fake this using polling) - Calls IFrame a hack ... Pot calling the kettle black, since Ajax itself is sort of a hack. Is it bad just because it's old? [MM Again, comes down to the comparison. XHR is a more intention-based, intuitive, API, although it's true that you won't care about that because you should use a wrapper lib anyway. Better argument is the extra functionality such as call tracking.] - Would like better explanation on what's so bad about IFrames. [TODO Include x-reference in IFrame Solution. Also mention the portable wrappers in the Solution, ie you shouldn't actually care/know which you're using is the more pertinent issue here.] - I'm feeling historical. The room we used to sit in is the room where the original Mosaic web browser developers sat. Continuously astonished in the web industry, using things that in ways they weren't invented for. Go down this list, frames, tables ... Ungodly mess, but really impressed, poster child for pragmatism and "worse is better". IFrame is a typical example. - I didn't get any feel on whether I would use one or the other. - Intrigued by the history of JS. Knowing that IFrame predated XHR because features that made it easier to do the second came along in 2003. Whether it needs to be here, not sure. [TODO Sidebar?]

=============================================================== 49:00 HTTP Streaming

Is it competition for the other two?  
  - Different problem (push/streaming)
  - "How can the browser communicate with the server?" Same
    problem as the other two.
    - I don't know, it turns the table. Little pattern device
      of using the same problem with different solutions may
      be okay here. Here, the forces would be different.
      Could make the case for having the same problem.  [TODO
      Change the problem statement, just enough to make it a
      little different from previous two.]

What would make you choose this over the others?
  - Changes coming from lots of other sources, not just the
    client.
  - e.g. Chat system.
  - I don't want to do this. Don't want to grow the system
    ...
    - But scaleability is oversold. You'll never be like
      EBay, don't need to scale up like that.  [TODO Good
      point, mention in the pattern.]
    - Our wiki - 4-5 hits per second - can handle that, but
      not scaleable.  Wikipedia is not a wiki in that sense,
      pages don't change because I believe something like 90%
      of all edits are done by 200 people, these are official
      wikipedia authors. Specific process.
    - Doesn't fit into proxies. Caching etc doesn't ddeal
      with longer responses.

Long refactoring illustration here. Do the others have one?
  - Streaming wiki demo.
  - Seemed nice to refactor in this way.
  - The group is looking at the live version on the web -
    "There's about a half dozen laptops in it for the
    author's information". It worked.  [MM Phew]

=============================================================== 1:20 - I didn't get the feel of which one to use. - Was hidden in the Alternatives section [MM TODO Emphasise this in the partintro, maybe in the solutions]

====== Next time: Different patterns - Problem with web version [MM Incidentally, the wiki publishing hasn't worked out ideally, didn't get the full benefit as I didn't open up the wiki (and still haven't due to spam). Ideally would have better PS format. (Blogged about printing from the web a yr ago as it happens.)] - Being on the web doesn't seem to affect (ie drop) sales. [MM We'll soon find out...:-)]

HTTP Streaming: An Alternative to Polling the Server

If Ajax apps are to be rich, there must be a way for the server to pass new information to the browser. For example, new stock quotes or an instant message someone else just sent you. But the browser’s not a server, so the server can’t initiate an HTTP connection to alert the browser. The standard way to deal with this dilemma is Periodic Refresh, i.e. having the browser poll the server every few seconds. But that’s not the only solution.

The recent podcast on Web Remoting includes a discussion of the HTTP Streaming pattern. By continuing to stream information from the server, without closing the connection, you can keep the browser content fresh. I wasn’t aware that it was being used much on the public web, since it can be costly, but I recently discovered JotLive (which is only semi-public since it requires registration) is indeed using it. Do you know any other examples?

Ajaxian.com’s interview with Abe Fettig of JotLive:

How do you handle the “live” part? Polling?

We’re using a (very slightly modified) version of LivePage, which Donovan Preston wrote as part of Nevow, a Python library for building web applications using the Twisted networking framework (which I just wrote a book on: Twisted Network Programming Essentials). LivePage doesn’t use polling. Instead, it uses a clever technique where each browser keeps an open XMLHTTP request to the server at all times, opening a new connection each time the old one closes. That way every client viewing the page is constantly waiting for a response from the server. When the server wants to send a message to a client, it uses the currently open request. So there’s no waiting.

A few (edited) extracts from the HTTP Streaming pattern:

Alternative Pattern: Periodic Refresh is an obvious alternative to HTTP Streaming. It fakes a long-lived connection by frequently polling the server. Generally, Periodic Refresh is more scaleable and easier to implement in a portable, robust, manner. However, HTTP Streaming can deliver more timely data, so consider it for systems, such as intranets, where there are less simultaneous users, you have some control over the infrastructure, and each connection carries a relatively high value.

Refactoring Illustration: The Basic Wiki Demo, which uses Periodic Refresh, has been refactored to use [http://ajaxify.com/run/wiki/streaming](HTTP Streaming).

Solution:
Stream server data in the response of a long-lived HTTP connection. Most web services do some processing, send back a response, and immediately exit. But in this pattern, they keep the connection open by running a long loop. The server script uses event registration or some other technique to detect any state changes. As soon as a state change occurs, it pushes new data to the outgoing stream and flushes it, but doesn’t actually close it. Meanwhile, the browser must ensure the user-interface reflects the new data. This pattern discusses a couple of techniques for Streaming HTTP, which I refer to as “Page Streaming” and “Service Streaming”.
“Page Streaming” involves streaming the original page response. Here, the server immediately outputs an initial page and flushes the stream, but keeps it open. It then proceeds to alter it over time by outputting embedded scripts that manipulate the DOM. The browser’s still officially writing the initial page out, so when it encounters a complete <script> tag, it will execute the script immediately. A simple demo is available at http://ajaxify.com/run/streaming/.
…(illustration and problems)…
“Service Streaming” is a step towards solving these problems, though it doesn’t work on all browsers. The technique relies on XMLHttpRequest Call (or a similar remoting technology like IFrame_Call). This time, it’s an XMLHttpRequest connection that’s long-lived, instead of the initial page load. There’s more flexibility regarding length and frequency of connections. You could load the page normally, then start streaming for thirty seconds when the user clicks a button. Or you could start streaming once the page is loaded, and keep resetting the connection every thirty seconds. Having a range of options helps immeasurably, given that HTTP Streaming is constrained by the capabilities of the server, the browsers, and the network.

Experiments suggest that the Page Streaming technique does work on both IE and Firefox ([1]), but Service Streaming only works on Firefox, whether XMLHTTPRequest ([2]) or IFrame ([3]) is used. In both cases, IE suppresses the response until its complete. You could claim that’s either a bug or a feature; but either way, it works against HTTP Streaming.

Donovan Preston explains the technique he uses in Nevow, which overcomes this problem:

When the main page loads, an XHR (XMLHttpRequest) makes an “output conduit” request. If the server has collected any events between the main page rendering and the output conduit request rendering, it sends them immediately. If it has not, it waits until an event arrives and sends it over the output conduit. Any event from the server to the client causes the server to close the output conduit request. Any time the server closes the output conduit request, the client immediately reopens a new one. If the server hasn’t received an event for the client in 30 seconds, it sends a noop (the javascript “null”) and closes the request.

Basics of Ajax 2 of 3: Web Remoting (XMLHttpRequest etc) (Podcast)

Ajax Basics 2 of 3

This is the second of three podcasts on the basic Ajax patterns.

  • Podcast 1: Display Patterns and the DOM.
  • Podcast 2: Web Remoting – XMLHttpRequest, IFrame Call, HTTP Streaming.
  • Podcast 3: Dynamic Behaviour – Events and Timing.

Podcast 2: Web Remoting (XMLHttpRequest, IFrame, HTTP Streaming)

Click to download the Podcast. You can also subscribe to the
feed if you want future podcasts automatically downloaded - check out the
podcast FAQ at http://podca.st.

This 75 minute podcast covers web remoting concepts and the following specific patterns:

  • XMLHttpRequest Call Use XMLHttpRequest objects for browser-server communication. (05:00)
  • IFrame Call Use IFrames for browser-server communication. (31:45)
  • HTTP Streaming Stream server data in the response of a long-lived HTTP connection. (47:00)


Please ignore this bit, I’m claiming My Odeo Channel (odeo/bdd768d9acefcad9)