Brought to you by renkoo Dojo SitePen

Dylan Schiemann

Real World Ajax

June 5, 2006

Slides http://dylan.io/rwa/

  • Why?
  • Demos
  • Techniques

Real-time World

traffic
NYC Cab
NYC Ads
IM
original source: http://flickr.com/photos/goldberg/127148419/

web: forms, content, pages, zero-install

desktop: responsive and synchronized UI, stable, local storage

mobile: always with you, "live"

  • DOM-centric approach is difficult for apps
  • Single document assumptions are difficult
  • Mutation events are a hack, not widely supported, and hard to use
  • Why?
  • Demos
  • Techniques
Renkoo
Greenplum MPP
original source: http://www.flickr.com/photos/ndrwfgg/61864434/
  • Why?
  • Demos
  • Techniques
  • Ajax: poll
  • Comet: push + persistent connection
Comet

In theory...

DOM Events are "a platform- and language-neutral interface that gives to programs and scripts a generic event system.

In reality...

  • great for user input events
  • ok for node mutations
  • cumbersome for application logic

A good event system: "Like crack for web developers"

Dojo Toolkit Event System Goals

  • DOM events + implementation quirks
  • method to method calls
  • server-client communication
  • AOP advice
  • topics (publisher/subscriber)

<p id="foo">foo</p>
function handler(evt) {alert(evt.innerHTML);}

foo

  • DOM syntax: document.getElementById("foo").addEventListener( "click", handler, false);
  • Dojo: dojo.event.connect( dojo.byId("foo"), "onclick", handler);
  • MochiKit: connect( $("foo"), "onclick", handler);
  • Prototype: Event.observe( $("foo"), "click", handler, false);
  • YUI: YAHOO.util.Event.addListener( "foo", "click", handler);

function foo() { dojo.debug("foo"); } function bar() { dojo.debug("bar"); }

  • Browser default: modify foo with a call to bar
  • Dojo: dojo.event.connect(dj_global, "foo", dj_global, "bar");
  • MochiKit: connect(dj_global, "foo", dj_global, "bar");
  • Prototype: modify foo with a call to bar
  • YUI: use publish/subscribe and custom events, or modify foo

var listeningObject = function() { this.onUpdateDate = function(evt) { } }
var filterObject = { "foo": "fooValue", "bar": "barValue" // params to pass or mutate }

  • Browser default, MochiKit, Prototype: not implemented
  • Dojo, Yahoo implement it

dojo.event.topic.publish("updateDate/startDate", "filterObject");
dojo.event.topic.subscribe("updateDate/startDate", listeningObject, "onUpdateDate");

function PublishObject(name) {
 this.name = name;
 this.testEvent = new YAHOO.util.CustomEvent("testEvent", this);
}
function SubscribeObject(name, pubObj) {
 this.name = name;
 this.pubObj = pubObj;
 this.pubObj.testEvent.subscribe(this.onTestEvent, this);
}
SubscribeObject.prototype.onTestEvent = function(type, args, me) {
 /* do something; */
}
var pub = new PublishObject("testPub");
var sub = new SubscribeObject("testSub");
pub.testEvent.fire(filterObject);

AOP style advice to interject and interrupt the call order and arguments. Of toolkits reviewed, only found in Dojo.

  • after advice (default dojo.event.connect behavior)
  • before (call target before source)
  • before-around and after-around (manipulate the inputs and outputs of the source function, useful for matching call structures, etc.)
  • dojo.event.connect("before", this, "onFoo", this, "onBar");
  • More details: http://dojotoolkit.org/docs/dojo_event_system.html
  • the publish/subscribe concept works really well here
  • Python inspired Deferreds in Dojo and MochiKit also useful
  • wrap XHR and comet requests inside event handlers and define callbacks
  • repubsub.RepubsubIO.subscribe("/socialevents/" + this.eventId + "/responseStatusTotals", this, "setTallies", null, 1, null);
  • tallies tallies
  • HTTP 1.1 chunked encoding
  • Long-lived http connection is kept alive in a hidden iframe
  • Content (data/events) is sent from server to client
  • Incremental rendering allows incremental processing and event handling (various hacks and browser differences)
  • HTTP/1.1 200 OK
    Content-Type: text/html; charset=UTF-8
    Transfer-Encoding: chunked
  • JavaScript code to subscribe, publish, route, and dispatch events
  • Optimized for large number of long-lived http connections
  • Two primary types: one is just a tunnel for pushing events and data from the server to the client
  • The other is an event server itself, with data stored in topics, using the same publish/subscribe model
pubsub lightstreamer jetty
  • mod_pubsub and repubsub (built on top of Twisted Python)
  • Nevow/LivePage
  • DWR
  • Lightstreamer
  • Jetty
  • KnowNow
  • ShortBus
  • Dojo is working to provide dojo.io wrappers for various servers
  • repubsub has a dojo client module
  • All have some standalone clients
  • Clients are not just JavaScript, but can be server languages as well (useful for testing, comm across layers of web applications)
  • Try to write all pieces of UI with update methods that are easy to slide into the publish/subscribe model
  • Use AOP advice and other techniques to avoid circular UI updates
  • Debugging more important than ever as more JavaScript debuggers on the market today crash or get confused with Comet
  • Local event dispatcher to route events from server topics to client-side topics
  • Update application states, return data to server, read data stored locally for offline modes
  • This presentation uses the Dojo Show widget, inspired by Eric Meyer's S5 widget

<div dojoType="showslide" title="Brought to You by the Dojo Show Widget">
 <ul>
  <li>This presentation uses the Dojo Show widget, inspired by Eric Meyer's S5 widget</li>
 </ul>
</div>

  • Thank you for coming!
  • Thanks to Dojo, Renkoo, and SitePen
  • Special thanks to Dion, Jeremy, and the other sys-con media people
  • http://dylan.io/rwa/