This application uses Google Maps to show the results, COMET for the distributed events that publish the new coordinates, and Adobe AIR as a deployment method. It also contains an application developed for Windows Mobile GPS devices that publishes the coordinates to the server.
Archive for the ‘COMET’ Category
Tracking system developed using Comet, Google Maps and Adobe Air
Posted by Vinay on January 17, 2009
Posted in COMET | Tagged: Adobe AIR, COMET, Windows Mobile GPS device | Leave a Comment »
moo-comet : Comet Techniques using Javascript
Posted by Vinay on January 17, 2009
About
Request.Comet is a simple javascript class to create cross browser Comet(Reverse Ajax) applications easily. It provides realtime data transfers between client and server and can be used with any server-sided language.
Posted in COMET | Tagged: ajax, COMET, javascript, mootools | Leave a Comment »
pi.comet – Comet (Reverse Ajax) applications
Posted by Vinay on January 17, 2009
Posted in COMET | Tagged: ajax, COMET, debugger, debugging, dhtml, firebug, javascript, pushajax, reverseajax | Leave a Comment »
Evolution of COMET
Posted by Vinay on November 18, 2008
Introduction
COMET is a style of data transmission that is neither traditional nor Ajax.
Traditionally, web pages have been delivered to the client only when the client requested it. For every client request, the browser initiates an HTTP connection to the web server, which then returns the data and the connection is closed. The drawback of this approach is that the page displayed is updated only when the user explicitly refreshes the page or moves to a new page. Since transferring entire pages takes a long time, refreshing pages introduces a long latency.
To solve this problem, Ajax can be used which allows the web browser to request only that part of the web page that has changed and update that portion accordingly. Since the overall data transferred is reduced, latency is also reduced. But this practice suffers from the problem that the client has to request some data before it will be sent by the server.
A solution would be to design the application such that it will intermittently poll the server to find out if the event has occurred. But this is not an elegant solution as the application will waste a lot of time querying for the completion of the event, thereby directly impacting the responsiveness of the application.
A better solution would be for the server to send a message to the client when the event occurs, without the client having to ask for it. Such a client will not have to check with the server periodically; rather it can continue with other work and work on the data generated by the event when it has been pushed by the server. This style of event-driven, server-push data streaming is “Comet”.
The continued evolution of HTML
The HyperText Markup Language (HTML) has long been the standard for Web-based interaction. It is designed to display text and images in a Web browser. Its simple publication and viewing model has helped develop the World Wide Web into the global phenomenon. But users wanted web applications that provide a desktop-like user experience and HTML’s page-oriented model falls short.
Ajax is a design approach and a set of techniques for delivering a highly interactive, desktop-like user experience for Web applications in popular HTML browsers. Ajax, which stands for Asynchronous JavaScript and XML, improves the user’s Web application experience while retaining the HTML benefits of server-based application deployment. Ajax achieves desktop-like Web pages by having parts of a page reload, instead of the entire page, in response to user input. Instead of whole-page refreshes, small amounts of data are exchanged with the server and the application remains usable by the end user.
Ajax builds on open standards that are widely available as native features (i.e., without plugins) in popular browsers. Ajax‘s incremental update techniques are obtained through built-in features such as JavaScript and the XMLHttpRequest API. Ajax developments often leverage JavaScript libraries that provide a cross-browser abstraction layer.
Dynamic and continuous user experience
The primary difference between HTML applications and Ajax applications is that Ajax allows users to interact with the application while the browser is communicating with the server.
HTML: click, wait, refresh
The following illustration shows the typical “click, wait and page refresh” experience that users get with HTML applications:
Figure 1: Client Server working in HTML Applications.
Defining Ajax
Ajax isn’t a technology. It’s really several technologies, each flourishing in its own right, coming together in powerful new ways. Ajax incorporates:
- standards-based presentation using XHTML and CSS;
- dynamic display and interaction using the Document Object Model;
- data interchange and manipulation using XML and XSLT;
- asynchronous data retrieval using XMLHttpRequest;
- and JavaScript binding everything together.
The classic web application model works like this: Most user actions in the interface trigger an HTTP request back to a web server. The server does processing and then returns an HTML page to the client.
Figure 2: The traditional model for web applications (left) compared to the Ajax model (right).
Every user action that normally would generate an HTTP request takes the form of a JavaScript call to the Ajax engine instead. Any response to a user action that doesn’t require a trip back to the server — such as simple data validation, editing data in memory, and even some navigation — the engine handles on its own. If the engine needs something from the server in order to respond — if it’s submitting data for processing, loading additional interface code, or retrieving new data — the engine makes those requests asynchronously, usually using XML, without stalling a user’s interaction with the application.
Desktop applications have a richness and responsiveness that has seemed out of reach on the Web. The same simplicity that enabled the Web’s rapid proliferation also creates a gap between the experiences we can provide and the experiences users can get from a desktop application. That gap is closing.
Ajax-powered user experience
Ajax minimizes the number of page refreshes because the client issues data requests to the server, not page requests. The Ajax application stays on the screen continuously while the Ajax engine handles data exchange with the server. Instead of page refreshes, the application updates only those parts of the screen affected by newly arrived data.
Figure 3: Client Sever working in AJAX Applications.
COMET
Defining Comet
The COMET applications use long-lived HTTP connections to reduce the latency with which messages are passed to the server. They do not poll the server occasionally. Instead the server has an open line of communication with which it can push data to the client.
Comparing Comet with Ajax
An Ajax application eliminates the start-stop-start-stop nature of interaction on the Web by introducing an intermediary Ajax engine between the user and the server.
Instead of loading a webpage, at the start of the session, the browser loads an Ajax engine — written in JavaScript. This engine is responsible for both rendering the interface the user sees and communicating with the server on the user’s behalf. The Ajax engine allows the user’s interaction with the application to happen asynchronously — independent of communication with the server. So the user experiences a faster response.
Figure 2: The synchronous interaction pattern of a traditional web application compared with the asynchronous pattern of an Ajax application and Comet web application.
But as is illustrated above, Comet applications deliver data to the client at any time, not only in response to user input. The data is delivered over a single, previously-opened connection. This approach reduces the latency for data delivery significantly.
While Comet is similar to Ajax in that it’s asynchronous, applications that implement the Comet style can communicate state changes with almost negligible latency. This makes it suitable for many types of monitoring and multi-user collaboration applications which would otherwise be difficult or impossible to handle in a browser without plug-ins.
Why Is Comet Better For Users?
- Regular Ajax improves the responsiveness of a UI for a single user, but at the cost of allowing the context to go stale for long-lived pages. Changes to data from others users is lost until a user refreshes the whole page. The user has to either wait until they perform some action which would kick off a request to see the updated state from other users or request changes from the server at some interval (called polling). Applications that employ the Comet technique can avoid this problem by pushing updates to all clients as they happen. UI state does not go out of sync and everyone using an application can easily understand what their changes will mean for other users.
- Ajax improves single-user responsiveness. Comet improves application responsiveness for collaborative, multi-user applications and does it without the performance restrictions associated with intermittent polling.
Endnotes
Comet is a new name for an old set of concepts. Since the Web is a multiuser experience, single interaction updates aren’t enough. Users in the same space need live updates of their own changes and the changes others make. Updates to content affect available actions. Stake context may mean the wrong decision. If the Web is a conversation, then stale context kills. When you create a page, or tag a picture, or something else, you’re chaining context. Conversation mediums are defined by latency, interrupt, and bandwidth. Conversations are ordered events. Granular interfaces require granular events. Granular conversations are more immediate (IM vs. email). Social web apps just batch changes today. There are no effective ways to “subscribe” to server events today.
Event broadcast requires synchronization. Comet is a technique for pushing data from the server. It is a new term, but old technique. This is enabled by long-lived HTTP connections instead of polling. There are similarities to AJAX: no new plugins, plain-old HTTP, asynchronous, broad browser support.
In an AJAX application, the client drives the interaction. The problem is that context and manipulated content go stale at different times.
Comet application fight lag by avoiding HTTP and TCP/IP set-up and tear-down and a single connection is re-used. But the problem with AJAX is polling latency which Comet avoids. The solution is to transfer only the necessary data, exactly when it’s most relevant.
There are two implementation techniques:
- Long-polling where you reconnect after every datagram. This is simple to implement with XmlHTTPRequests. Another method is to use multi-part XmlHTTPRequests. This works differently different browsers. No known system does this portably today.
- Another technique is an iframe or browser frame that receives script blocks and uses progressive rendering. This is highly portable and allows connections to subdomains. The connection only closes when there’s an error of the connection recycles.
Comet is need if users are all trying to do the same things at the same place to some piece of data. If the data can go stale and no one notices, then COMET is not needed.
Systems that use Comet
GMail, GTalk, JotLive, Renkoo, Meebo and others. Note that Comet isn’t a framework or toolset, it is a concept.
References:
Posted in COMET | Tagged: COMET | Leave a Comment »
COMET – Beyond Ajax
Posted by Vinay on November 18, 2008
Introduction
In web applications, traditionally web pages are delivered to the client only when the client requests them. For every client request, the browser initiates an HTTP connection to the web server, which then returns the data and the connection is closed. The drawback of this approach is that the page displayed is updated only when the user explicitly refreshes the page or moves to a new page. Since transferring entire pages takes a long time, refreshing pages introduces a long latency.
To solve this problem, Ajax can be used which allows the web browser to request only that part of the web page that has changed and update that portion accordingly. Since the overall data transferred is reduced, latency is also reduced and overall responsiveness of the web site hosting the application increases. Further, by using asynchronous background data transfer, where the user works with partly received data as the rest of the data is being retrieved, the responsiveness of the web application can be further increased.
But this practice also suffers from the problem that the client has to request some data before it will be sent by the server. This problem becomes a major hurdle when designing applications which have to wait for some event to occur at the server side, such as some other user sending some data to the server, before it can proceed, but has no information when the event will occur.
A solution would be to design the application such that it will intermittently poll the server to find out if the event has occurred. But this is not an elegant solution as the application will waste a lot of time querying for the completion of the event, thereby directly impacting the responsiveness of the application. In addition, a lot of network bandwidth will be wasted.
Comet gives the better solution for this. It allows the server to send a message to the client when the event occurs, without the client having to ask for it. Such a client will not have to check with the server periodically, rather it can continue with other work on the data generated by the event when it has been pushed by the server.
What is Comet?
- Comet is an advanced programming technique that enables web servers to send data to the client without having any need for the client to request it. It allows creation of event-driven web applications which are hosted in the browser.
- Comet is a new term but old technology; they use long-lived HTTP connections to reduce the latency with which messages are passed to the server.
- In essence, they do not poll the server occasionally; Instead the server has an open line of communication with which it can push data to the client
How Comet differs from Ajax
Comet applications can deliver data to the client at any time, not only in response to user input. The data is delivered over a single, previously-opened connection. This approach reduces the latency for data delivery significantly.
The architecture relies on a view of data which is event driven on both sides of the HTTP connection. Unlike Ajax, applications that implement the Comet style can communicate state changes with almost negligible latency. This makes it suitable for many types of monitoring and multi-user collaboration applications which would otherwise be difficult or impossible to handle in a browser without plugins.In Comet applications, servers push data in addition to client requesting it.
Similarities between Comet and Ajax
- No plugins
- Plain old HTTP
- Asynchronous
- Broad browser support
Why Is Comet Better For Users?
Regular Ajax improves the responsiveness of a UI for a single user, but at the cost of allowing the context to go “stale” for long-lived pages. Changes to data from others users is lost until a user refreshes the whole page. An application can alternately return to the “bad old days” and maintain some sort of state mechanism by which it tells client about changes since the last time they’ve communicated. The user has to either wait until they perform some action which would kick off a request to see the updated state from other users (which might impact the action they wanted to perform!) or request changes from the server at some interval (called “polling”).
Since the web is inherently multi-user, it’s pretty obvious that regular Ajax imposes usability and transparency hurdles for users. Applications that employ the Comet technique can avoid this problem by pushing updates to all clients as they happen. UI state does not go out of sync and everyone using an application can easily understand what their changes will mean for other users. Ajax improves single-user responsiveness.
Comet improves application responsiveness for collaborative, multi-user applications and does it without the performance issues associated with intermittent polling.
Applications implementing comet
Below mentioned are few familiar applications implementing comet.
- Gmail+Gtalk
- Jot Live
- Renkoo
- Meebo
References:
[1] http://cbcg.net/talks/comet/
[2] http://alex.dojotoolkit.org/wp-content/LowLatencyData.html
Posted in COMET | Tagged: COMET, comet beyond Ajax | Leave a Comment »
ItsNAT – New Java Based Comet Tool
Posted by Vinay on October 18, 2008
ItsNat is an innovative open source (dual licensed, GNU Affero General Public License v3/commercial license for closed source projects) Java AJAX Component based Web Framework. It offers a natural approach to the modern web development. Why natural? ItsNat leverages the old tools to build the new AJAX based Web 2.0 applications: pure (X)HTML templates, pure Java W3C DOM!. ItsNat is server centric using a unique approach called TBITS, “The Browser Is The Server”: ItsNat simulates a Universal W3C Java Browser at the server, with ItsNat the server mimics the behavior of a web browser, containing a W3C DOM Level 2 node tree and receiving W3C DOM Events.
ItsNat provides many more things: web-continuations (continue events), user defined events, timers, long running server tasks,COMET, DOM utils (to simplify DOM manipulation), resolution of ${} based variables in markup, ElementCSSInlineStylesupport in the server, automatic page remote/view control of other users/sessions!!, XML generation, non-HTML namepaces support like pure SVG with AJAX and SVG embedded in XHTML, JavaScript generation utilities, events fired by the server sent to the client simulating user actions for instance to test the view using the server, custom pretty URLs, previous/forward document navigation (pull and push referrers) with back/forward button support, degraded modes (AJAX disabled and JavaScript disabled modes) etc.
ItsNat provides a web based Component System too. These components are AJAX based from the scratch inspired in Swing and reusing Swing as far as possible such as data and selection models (but is not a forced Swing clone in web). Components included: several button types, text based components, labels, lists, tables, trees (all of them with content editable “in place”)… In ItsNat every DOM element or element group can be a component.
Supported desktop browsers: Internet Explorer 6+, FireFox 1+, Safari 3+, Opera 9+, Google Chrome, QtWebKit and QtJambi (Qt 4.4), Arora (QtWebKit based)
Supported mobile browsers: Opera Mini 4, Opera Mobile 8.6, NetFront 3.5, Minimo 0.2, IE Mobile of Windows Mobile 6, iPhone/iPod Touch/iPhone SDK, Android (v0.9 Beta r1), S60WebKit (S60 3rd), Iris 1.0.8 and QtWebKit of Qt Embedded for Linux and Windows CE (Qt 4.4).
Links
Posted in COMET | Tagged: COMET, COMET - Java Web Application Framework, Java Web Application Framework, New Java Based Comet Tool | Leave a Comment »
Comet Implementation in jQuery
Posted by Vinay on October 6, 2008
Implementation of Bayeux protocol for jQuery. Current supports, handshake, subscriptions, binding callbacks into the jQuery event system based on channel names.
You can download this plugin here
Posted in COMET | Tagged: COMET, jquery, jquery plugin comet | Leave a Comment »
HTTP Streaming and Internet Explorer
Posted by Vinay on September 25, 2008
Michael Carter wrote about the trials and tribulations of getting HTTP streaming with IE. He knew that the htmlfile ActiveX object was the key, but kept getting errors.
Then he stumbled on the solution:
We happen to be in luck. Changing JavaScript variables, including Array functions, seems okay as far as the gods of htmlfile streaming are concerned. So our solution is to simply append event payloads to an array from within the iframe, have the parent window use use a timer loop (’setInterval’) to periodically check the array for new messages, and then pass them to the callback. It’s not as elegant as I’d like…but it beats all the other techniques I’ve tried.
Why not just call a function attached the parent window, you wonder? It turns out htmlfile’s iframe doesn’t care where the function object lives; instead, it cares which thread is used to execute the code. The htmlfile thread is a capricious beast, and will rebel when employed to do too much DOM work. The effect of setInterval is to move the actual DOM manipulations to a thread that is perfectly safe for that sort of scripting. This fix works for IE 5.01+.
Michael just put up another post that details the solution after learning about the nuances of IE. He ended up using the following code:
-
function connect_htmlfile(url, callback) {
-
// no more ‘var transferDoc…’
-
transferDoc = new ActiveXObject(“htmlfile”);
-
transferDoc.open();
-
transferDoc.write(
-
“<html><script>” +
-
“document.domain=’” + document.domain + “‘;” +
-
“</script></html>”);
-
transferDoc.close();
-
var ifrDiv = transferDoc.createElement(“div”);
-
transferDoc.body.appendChild(ifrDiv);
-
ifrDiv.innerHTML = “<iframe src=’” + url + “‘></iframe>”;
-
transferDoc.callback = callback;
-
}
And in the iframe:
-
<script>parent.callback(["arbitrary", "data", ["goes", "here"]);</script>
Posted in COMET | Tagged: Streaming HTTP | Leave a Comment »
Long Polling vs Forever Frame
Posted by Vinay on September 25, 2008
One of the oft-cited advantages of forever frame over long polling is that it does not suffer from the 3x max latency issue. This is when an event occurs the instant after a long poll response is sent to a client, so the event must wait for that response and the subsequent long poll request before sending a response containing that event. Thus while the average latency of long polling is very good, the theoretical max latency is 3x the average latency, which is the time taken to transit the network one-way.
Forever frame is said not to suffer from this issue, as it can send a response back at any time, even the instant after a previous event has been sent. Strictly speaking, that is not always the case, as forever frame implementations also need to terminate responses and issue new requests, at the very least to prevent memory leaks on the client. But for the purposes of this musing, let’s assume that it is true.
Does this theoretical lowering of the maximum latency actually enable any applications to be developed that would be impossible with the 3x max latency? For example, could forever frame be used to implement a first person shooter game that would be unplayable with long polling injecting a 3x latency on occasions (normally just as you charge into the room full of enemy guns lagging…).
Unfortunately, I think not. The problem is that comet will never be suitable for any application that cannot accept a bit of jitter in the application latency. Comet can achieve great average latency, often <100ms over the internet, but it is always going to suffer from the possibility of an occasional long delay.
The reason is that TCP/IP is by definition the transport that will be used for comet (that adheres to open standards) and TCP/IP is simply not a protocol that can guarantee constant low latency. Like long polling, TCP/IP gives very good average latency, but all it takes is 1 dropped packet and you will incur a TCP/IP timeout and resend, which by definition will be at least 3 x the network traversal time (sender must wait at least 2x network time before deciding that the ack will never come, then it must resend). Sure TCP/IP has lots of tricks and optimizations that are designed to help with latency for missed packets (e.g. fast resend, piggyback ack), but they rely on other traffic being sent in order to quickly detect the dropped packet. If a lone event is sent in a single packet, then at least 3x latency will result. One could even argue that the client’s need to send a new poll request with long polling will provide a convenient data packet on which an ack can piggyback, and could improve latency in some situations.
So any application that cannot tolerate 3x max latency is an application that should not be considered for comet. Comet is ideal for applications that thrive on good average latency, but that can tolerate the odd delay. For such applications, long polling is a good match and the theoretical latency gains of forever frame are probably just that—theoretical.
Posted in COMET | Tagged: COMET | Leave a Comment »
The Future of Comet: HTML 5’s Server-Sent Events
Posted by Vinay on September 25, 2008
http://cometdaily.com/2008/01/10/the-future-of-comet-part-2-html-5′s-server-sent-events/ by Jacob Rus
HTML 5 and Comet
Comet doesn’t have to be a hack. Currently, Comet relies on undocumented loopholes and workarounds, each one with some drawbacks. We can make Comet work effectively in every browser, using streaming transports on subdomains of the same second-level domain, or using script tag long polling across domains. But this leaves Comet developers implementing (and more frustratingly, debugging) several transports across several browsers. Traps are numerous and easy to stumble into.
Recognizing the benefit of a straight-forward, standardized Comet technique, the WHATWG’s HTML 5 specification includes sections about server-sent events, and a new event-source element, which aim to de-hackify Comet. For now, only Opera has implemented these, and its implementation remains incomplete, but both Mozilla and Apple have committed to HTML 5, and an implementation is at least in-the-works for Safari.
Every Comet developer should familiarize himself with these specifications, because they provide the best streaming transport for Opera since version 8.5, and can only grow in importance as browsers adopt them. Furthermore, HTML 5 is a work-in-progress, and now is the best time to provide feedback to the WHATWG. Those interested in the future of Comet should comment now, before the specifications have been repeatedly implemented and can no longer be easily modified.
Basics of the server-sent events data format
The server-sent events portion of HTML 5 defines a data format for streaming events to web browsers, and an associated DOM API for accessing those events, by attaching callback functions to particular named event types. The format, which is sent by a Comet server with content type application/x-dom-event-stream, is straight-forward. Each event is made up of key-value pairs. For example:
key 1: this is the value associated with key 1
key 2: this value for key 2 stretches
key 2: over three lines, which are concatenated
key 2: by a browser supporting server-sent events
; these lines, which each begin with a `;`, are
; comments, and are ignored by the browser
key 1: after a pair of newlines, this is a new
key 1: event, with its own set of key-value pairs
; the following key has an empty corresponding value
empty key
...
Each key-value pair is known as a field, and several special fields are defined in the specification. In particular, the Event field names the event as a specific type. The browser can attach different callback functions to specific named event types. If omitted, the event type is assumed to be message. Also, though it is only mentioned in examples, the data field is useful for our event payloads.
So an event stream sent by Orbited might look something like:
Event: orbited
data: this is our event payload for the
data: first Orbited event
Event: orbited
data: this is the payload for the second
data: Orbited event
Event: ping
data: \o/
Event: orbited
data: here's the third Orbited event
...
The specification mandates that all files are UTF-8, but considers any of carriage return (\r), line feed (\n), or both (\r\n) an acceptable newline—in the browser, multiple lines of a single field are joined with \n alone.
The event-source element
Server-sent events are received by objects supporting the RemoteEventTarget interface, which merely means that they support two methods, addEventSource and removeEventSource, each of which takes a URI string as input, and adds or removes it, respectively, from the list of event sources for the object.
In addition to any JavaScript objects supporting server-sent events, HTML 5 defines an event-source HTML element, which declaratively indicates the use of a Comet source in a web page. As well as supporting the addEventSource and removeEventSource methods, the event-source element has a src attribute. When the src is changed, the event-source closes its previous connection, and opens a new Comet connection to the new URI.
Cross-domain usage
HTML 5 allows connections across domains, through use of the Access-Control HTTP header, as defined in a separate W3C specification (which applies identically to normal XHR usage and to server-sent events). A request is made for a resource as usual, but if that resource on the server (in this case, an event stream from a Comet server), includes the Access-Control HTTP header with values allowing the use of the resources, browsers will treat it as if it came from the same domain as the main document. If the header is not found, or if it denies the requested use, browsers will behave as if the resource does not exist (so that denied requests reveal no information about the resource).
Additionally, HTML 5 defines a “cross-document messaging” mechanism, which allows cooperation between documents (perhaps in iframes, etc.) from different domains, using a postMessage function.
Opera’s implementation
Opera has, since version 8.5, implemented a subset of these HTML 5 technologies. Opera versions since 8.5 support the event-source element, and recent versions have pure-JavaScript interfaces as well.
To support versions back to 8.5, we must create event-source elements, set their src attribute, and attach them to the document. Then we can add “event listener” callback functions to the event-source for each type of named event in the event stream. In Orbited, we use the following JavaScript to accomplish this:
connect_server_sent_events: function () {
var es = document.createElement('event-source');
es.setAttribute('src', this.url);
document.body.appendChild(es);
var event_cb = this.event_cb;
es.addEventListener('orbited', function (event) {
var data = eval(event.data);
if (typeof data !== 'undefined') {
event_cb(data);
}
}, false);
},
Where this.event_cb is some callback function, a property of the Orbited object, which will receive the event payload of every orbited event. By default we send payloads in JSON format, so evaling each yields a JavaScript object.
Also, it is quite easy to test browsers for server-sent events support from JavaScript, using code something like:
if ((typeof window.addEventStream) === 'function') {
// ... browser supports server sent events
} else {
// ... no support. fall back on another transport
}
Caveats
Opera’s implementation differs from the specification in a few key ways, however, so Comet application authors must be careful.
- Opera ignores events without a defined
Eventfield, rather than assuming its value to bemessage. It is possible to include multiple named event types, attaching separate event listeners for each type. - Event payloads must be in the
datafield. A callback attached to the event source will receive aneventobject as input, withevent.dataset to the value of thedatafield. - At present, Opera only supports linefeed (
\n) characters as newlines in event streams, and will silently fail if carriage returns are used in newlines (\r\nand\rare not supported newlines).
Legacy support
Even though Opera is the only browser to natively implement server-sent events, it is possible for a Comet server to treat the last several versions of Safari and Firefox as if they did, with a few caveats. We can use a modified XHR streaming technique (as described in part 1), and implement our own parsing for the application/x-dom-event-stream format (at least the version supported by Opera) in JavaScript. To pull this off we must make one concession to Safari: 256 bytes of dummy data at the beginning of our event stream, so that Safari will begin incremental parsing.
Our Comet server can then be blissfully unaware that these browsers have no real server-sent event support, and we can get away with implementing only two transports on the server side: the iframe transport, supported by most browsers since at least 1999 or 2000, and—using the htmlfile ActiveX object—capable of a flawless user experience back to Internet Explorer 5.01; and server-sent events.
To make them still more compatible, we might be able to build support for event-source into Firefox and Safari using JavaScript alone, creating objects supporting the addEventSource, removeEventSource methods, and capable of dispatching named event types to event listeners. Adding such support would require deeper magic than I currently possess as a journeyman JavaScript hacker; if any masters can shed insight, please comment here, or shoot an email to the Orbited mailing list.
In Orbited, we have not yet tried reducing XHR streaming to server-sent events for Firefox and Safari, but it is on the to-do list.
Arbitrary DOM events and controversy
In addition to this straight-forward Comet transport, server-sent events provide more general, and potentially powerful, capabilities, whose complexity is somewhat controversial. Indeed, the whole server-sent events section of the specification currently includes a notice that it may be removed. I expect that it will change at least somewhat from its current form before the specification is finished.
The specification demands that every element supporting the EventTarget interface should also support the RemoteEventTarget interface. A Comet server can thereby send arbitrary DOM events to page elements. This includes events such as mouse clicks, key presses, etc. As specified, event streams can also include a Target field, which can target events to the top level of the document, or to specific element IDs. And browser vendors could, if they desired, add further objects supporting the RemoteEventTarget interface, potentially enabling declarative Comet applications.
So the theory goes. Many of us Comet developers, including Michael Carter and Alex Russell (in a recent IRC discussion), remain unconvinced that there is a benefit in pushing application logic from browser-side JavaScript to the server side. We expect that real-time applications will always have a significant need for client-side logic, so the specification may as well embrace that—and remain as simple as possible. Specification simplicity benefits not only browser vendors who must build conforming and compatible implementations but also Comet developers who must learn its ins and outs.
But I hope server-sent events are not scrapped altogether. Comet would benefit greatly from specification and intentional browser support. The version supported by Opera strikes a reasonable balance, meeting the needs of Comet developers without going beyond those needs.
Conclusion
With improving browser support, creation of more high-quality open-source Comet servers, better developer resources such as Comet Daily, and the examples provided by big-name Comet applications, Comet’s future looks bright. Any standardization efforts by browser vendors that further reduce barriers to entry will only lead to more and better Comet applications.
HTML 5 is coming, with at least Opera, Apple, and Mozilla committed to its adoption, and one way or another it will include improved Comet support. But the Comet-related portions of HTML 5 are still very much unfinished, and in need of feedback from browser vendors and from us, the community of Comet developers. The discussions are transparent and easy to join, and time for action is now. We should figure out what we need and tell the W3C and the WHATWG about it. They are all ears.
Posted in COMET | Tagged: future comet | 1 Comment »
Comet is Always Better Than Polling
Posted by Vinay on September 25, 2008
Comet techniques are advocated when your application needs low latency events to be delivered from the server to the browser. Comet can deliver sub-second latency for messages making possible web applications like chat, games and real-time monitoring of prices and states.
It is often asserted that for applications that don’t need low latency (e.g. email readers), traditional polling is a better alternative. However, some rudimentary analysis shows this assertion to be wrong, and that Comet techniques can be applied to all required latencies and event rates to provide improved data rates and average latencies.
For this analysis, I have considered polling vs. the long-polling technique where a server may hold a poll request for a period of time while waiting for events/messages to be delivered to the browser. In order to ensure that we are comparing apples with apples and oranges with oranges, I have compared configurations that provide the same maximum latency. For example, for a maximum latency of 10s, the polling technique must issue a poll every 10s and the average latency is half that. For the Comet technique long polling, a long poll needs to be issued 10s after the last long poll completes, but the server may hold the long poll for up to 300s while waiting for an event.
The attached spreadsheet contains the calculations, which I have graphed for 1s, 10s and 100s maximum latency for message rates of 1, 10, 100 and 1000 messages per second for 1000 users. The results show that the Comet long polling technique uses less bandwidth than polling in all situations, and uses significantly less bandwidth when the average period between messages is longer than the maximum latency:
Not only does Comet long-polling provide superior data rates, it also provides superior average latency. The Comet technique allows the average latency to be lower than the maximum latency because once the pause between polls is complete, the long poll is ready to respond immediately to events.
This analysis shows that for the worst case, when the message rate is high, load and latency for Comet long-polling are identical to traditional polling, and for most cases the load and latency are significantly better than traditional polling.
The calculations for these graphs are in this Comet vs Polling spreadsheet. The assumptions made are that all messages are equal in size (150Bytes) and that the message arrival times are randomly but uniformly distributed. A maximum long poll timeout of 240s is assumed. The Y axis of the graphs is logarithmic so larger differences appear smaller.
Posted in COMET | Tagged: COMET | 1 Comment »
The Long-Polling Technique
Posted by Vinay on September 25, 2008
The long-polling Comet technique is a technique that optimizes traditional polling to reduce latency.
Traditional polling sends an XMLHttpRequest to the server in fixed intervals. For example, open a new XMLHttpRequest every 15 seconds, receive an immediate response, and close the connection.
Long-polling sends a request to the server, but a response is not returned to the client until one is available. As soon as the connection is closed, either due to a response being received by the client or if a request times out, a new connection is initiated. The result is a significant reduction in latency because the server usually has a connection established when it is ready to return information to return to the client.
Posted in COMET | Tagged: COMET | 1 Comment »
The forever-frame technique
Posted by Vinay on September 25, 2008
http://cometdaily.com/2007/11/05/the-forever-frame-technique/
The forever-frame Comet technique is a true push implementation that is not based on polling, the XMLHttpRequest, or setting a dynamic script source. Instead, features of HTTP 1.1 originally intended for transfer and incremental rendering of very large documents are put to use to incrementally deliver data through an HTML iframe element.
This technique is very low-latency because it avoids HTTP and TCP/IP set-up and tear-down by reusing a single long-lived connection.
Chunked Encoding
Chunked Encoding is the feature in the HTTP 1.1 specification allowing a server to start sending a response before knowing its total length. This allows the server to break a complete response into smaller “chunks”, sending them in series. Responses are easy to identify because their header contains “Transfer-Encoding: chunked”. A specification for a message is as follows:
Chunked-Body = *chunk
last-chunk
trailer
CRLF
chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*(”0″) [ chunk-extension ] CRLF
chunk-extension= *( “;” chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)
Iframe
In typical Comet server implementations such as mod_pubsub, KnowNow, and Lightstreamer, a hidden iframe element is opened in the browser after page load, establishing a long-lived connection inside the hidden iframe. It is not supported in the current version of the Cometd client found in Dojo 1.0, but it will return in the near future. That said, it’s simply a matter of using the DOM to create a hidden iframe, and setting the source with the necessary parameters to communicate with your Comet server.
Incremental rendering and flushing
Browsers incrementally render chunked encoded documents after each chunk is rendered. Each chunk is wrapped in a script block, and executed with a function call in the Comet client library living in the parent document. Not every browser behaves well. For example, Internet Explorer requires a rendering element such as a <br /> tag, and Safari requires 1KB of data (usually sent in the form of whitespace), to force incremental rendering. The major Comet toolkits provides these workarounds automatically. In order to avoid excessive peak memory usage, the DOM nodes added to the iframe are typically removed after they are rendered.
Summary
The forever-frame technique uses HTTP 1.1 chunked encoding to establish a single, long-lived HTTP connection in a hidden iframe. Data is pushed incrementally from the server to the client over this connection, and rendered incrementally by your web browser.
Posted in COMET | Tagged: COMET, encoding, frame, XMLHttpRequest | 1 Comment »
The Future of Comet: Comet Today
Posted by Vinay on September 25, 2008
http://cometdaily.com/2007/12/11/the-future-of-comet-part-1-comet-today/
Comet is a giant hack. Even when it works flawlessly and efficiently, bringing us real-time interactive applications, deftly weaving around firewalls and browsers, avoiding unfriendly side effects, and cutting latency to near zero, it does so using mechanisms unforeseen by browser vendors, and unspecified by web standards.
Posted in COMET | Tagged: COMET | Leave a Comment »
Proposal for Native Comet Support for Browsers
Posted by Vinay on September 25, 2008
What if I had commit privileges on all the major browsers, the competence to add functionality in all the code bases, and wanted to add native Comet support in a form that was easily accessible to developers? What if we could use a native API that didn’t require the hacks of frame-based streaming, and didn’t face the cross-site and streaming limitations of XMLHttpRequest? Could we access Comet in a simple JavaScript API that works in a manner that servers could easily deliver messages to? I believe we could, and we could not only have easier Comet interaction, but also significantly improve the performance characteristics of both Ajax and Comet interaction in the process. I will describe a native implementation that not only provides simple techniques for Comet, but also provides some very interesting performance enhancements for general Ajax requests.
The first question is what level in the communication stack should native Comet be implemented at? HTTP is not mandated: Comet could be implemented at the TCP level or UDP could even be used. However, eliminating HTTP renders a vast number of application servers obsolete in their ability to communicate with the browser. Most web applications are built around HTTP. Requiring a different TCP or UDP protocol would negate substantial efforts to create open-connection capabilities in existing application servers, and would require significant architectural changes. A native Comet implementation should use HTTP-based Comet. With widespread investment and adoption, HTTP should be leveraged as much as possible to provide the foundation for Comet.
A second question would be what type of JavaScript interface to use. I am suggesting simply using the existing and familiar XMLHttpRequest API with some simple additions to achieve a powerful range of Comet capabilities. Obviously a new API could be used, but the existing XMLHttpRequest is widely adopted and understood. The XMLHttpRequest API provides comprehensive control and access over HTTP messaging.
Server Streamed Messaging
HTTP provides a streaming mechanism, but browser limitations and lack of message partitioning conspire to make it a shaky foundation for Comet. If all browsers properly implemented the interactive mode of XMLHttpRequest, content could be streamed to deliver asynchronous data from the server. However, IE doesn’t support this, and the browsers that do support streaming simply create an ever increasing string of content, continually devouring memory and requiring ad-hoc message partitioning. One could provide server initiated messaging by simply allowing ad hoc HTTP responses to be delivered on the TCP/IP connection without any requirements on correlated HTTP requests. However, this is clearly not allowed by the HTTP specification. Firefox has implemented support for the multipart/x-mixed-replace content type, which provides streaming with clear message partitioning without unbounded strings. While this is effective, this content type is semantically simply incorrect for many Comet usages. Often Comet is subscribing to a series of events, not resources that replace each other. If chat messages are being sent from a server, they are not intended to supersede the prior messages, but rather add to them. The multipart/x-mixed-replace content type is great for streaming web cams, but it is simply not the ideal solution for Comet. HTML 5 proposes to use server-sent events with the application/x-dom-event-stream content type to send DOM events. This approach is certainly not without merit. However, JavaScript interaction with a server requires routing all messages through a DOM element, and servers must place the data in a special DOM event formatting style. Handling these types of server-sent events would be very awkward with the XMLHttpRequest object, requiring a number of altered or new interface points.
In my last article, I pointed out the technique of encapsulating HTTP messages into content. I originally suggested the use of the multipart/digest content type, but after further thought, I believe that the message/http content type is actually more semantically correct since it directly indicates that the content will contain HTTP message(s), and this content type is also more compact because it doesn’t require boundaries. A native implementation could easily handle response streams with the XMLHttpRequest object in the same manner as Firefox handles a response with the multipart/x-mixed-replace content type. The message/http content type would not only be semantically correct, but headers can be included in each message to indicate status codes, request correlation, caching information, and more. This can also provide the means for RESTful semantics for Comet messages. The message/http content type could easily be handled by the XMLHttpRequest in the same way as Firefox handles the multipart/x-mixed-replace content type. Each new HTTP response in the stream could trigger the onreadystatechange handler and the content and response headers could easily be accessed with the standard XMLHttpRequest API.
Another advantage to encapsulating HTTP responses in a content stream is that gzip can be applied to compress the full inner HTTP responses. Normally gzip does not compress headers (since the headers negotiate the gzip), but with encapsulated HTTP responses, the outer response can negotiate and handle the gzip and the inner HTTP responses will be fully compressed (headers and content). HTTP headers are highly compressible when multiple responses are delivered in the same stream, meaning that this delivery mechanism can be highly efficient and compact on the wire. Each HTTP response may only have several bytes of overhead per message.
Client-Delivered Streaming
While there are several ways for JavaScript clients to consume server-delivered streaming data in existing browsers, there is simply no mechanism for client-delivered streaming. Once a browser sends request data to a server, it is basically impossible for JavaScript to coerce the browser to send any more data on that connection until a response is received and finished. The one exception is through HTTP pipelining, however HTTP pipelining is very inflexible because it requires responses to be received in the same order as requests. In a true asynchronous messaging system, a client should be able to deliver messages without placing constraints on the order of messages received from the server. The inability of a client to send data on an open HTTP connection is particularly problematic for Comet clients. A Comet connection may stay open for an extended period of the time, and the whole time that connection is essentially limited to one-way communication (the client is mute on that connection until the HTTP conversation has finished). Once request has been sent on an open connection, if the client needs to send additional data to the server (such as a request to subscribe to an additional resource) a new connection must be used. Creating new TCP connections is slow, and with the browser’s two connection limit, requests may be queued. Lifting the two-connection limit on browsers may seem attractive, but connections utilize valuable resources on the server, and using existing TCP connections is more efficient. By utilizing chunked encoding in HTTP requests, a native Comet implementation could also add support for client-delivered streaming. This ability could be accessed by adding a sendChunk method to the XMLHttpRequest API. Calling sendChunk instead of the normal send method would indicate a request transfer encoding of chunked, and it would send a chunk of data in the content stream and leave the content stream open for future chunks to be sent. The connection could always be terminated with the standard send method.
Once again, the message/http content type can be utilized to encapsulate multiple HTTP messages in this chunked content stream. This provides a standards-based way to partition messages in the client sent content stream, and follows the well understood HTTP protocol for sending messages. This capability can be achieved by manually constructing HTTP request messages and calling sendChunk. However, to simplify usage, an addHttpChunk method could be added to the XMLHttpRequest API. The addHttpChunk would take a single argument: an inner XMLHttpRequest object to be delivered inside the outer XMLHttpRequest object’s content stream. When a user calls the XMLHttpRequest.addHTTPChunk method, the provided inner XMLHttpRequest object would be associated with the outer XMLHttpRequest object. When a the send method was called on the inner XMLHttpRequest object, the HTTP message would be delivered as a data chunk in the containing message/http content stream. Multiple messages (HTTP requests) could then be delivered in a single request stream and a single connection. Responses could be correlated to requests by the Content-Location header, and the onreadystatechange handler could be called for inner XMLHttpRequests when the containing HTTP response content stream received a correlated HTTP response. Below is an example of the usage:
var cometXHR = new XMLHttpRequest;
cometXHR.open('POST','comet',true);
var xhr1 = new XMLHttpRequest;
cometXHR.addHttpChunk(xhr1);
xhr1.onreadystatechange=function(){...}
xhr.open('GET','/ticker1',true);
xhr.send();
var xhr2 = new XMLHttpRequest;
cometXHR.addHttpChunk(xhr2);
xhr2.onreadystatechange=function(){...}
xhr.open('GET','/ticker2',true);
xhr.send();
This would asynchronously send and receive embedded HTTP messages utilizing a single HTTP connection.
The ability to stream HTTP requests over a single connection does not solely benefit Comet applications. Standard pull-based Ajax application can benefit from this capability as well. In existing browsers, when multiple Ajax calls are made, each request must either create a new connection (unless there is an unused keep-alive connection available) or wait until a response is received on an existing connection. With request streaming, successive Ajax requests can be continuously delivered to the server without unnecessary delay and without creating new connections.
By combining the client-delivered streaming capabilities with the handling and partitioning of server-delivered streaming, a client could truly have asynchronous two-way communication with a server. A client could asynchronously send messages and receive messages from the server on the same HTTP/TCP connection.
Resource Subscription
A very simple resource subscription technique could also be included in the XMLHttpRequest API. Without any API additions, one could use my proposed When-Modified-After header. A client could trigger resource retrieval and subscription by simply including a When-Modified-After header with a beginning-of-the-epoch time (Wed, 1 Jan 1970 00:00:00 GMT) and indicating multipart response parsing (with the multipart property). The server could then return a response with a message/http content stream, and then immediately return the resource in a nested HTTP response in the entity content stream. The server could then keep the connection open and send any further modifications in the entity content stream as additional HTTP responses. Resource update HTTP responses could be a 200 with the entire new resource representation, 206 with an updated range, or 410 to indicate the resource was deleted. The XMLHttpRequest object could then call the onreadystatechange handler with each resource update, just as when the first HTTP response arrived. The XMLHttpRequest API could be augmented with a subscribe property, which when set to true could automatically include the When-Modified-After header. Developers would then have a very simple method for sending subscription requests using a familiar API.
Cached Resource until Updated
With a native modification to the browser in combination with the When-Modified-After header, an implementation could provide an interesting alternate behavior, which I believe is much more powerful than the simple approach above. When a XMLHttpRequest is made with the subscribe property set to true, and a cached copy of the resource is available, the browser could immediately return the cached copy and send a request to the server with the When-Modified-After header set to the date of the cached copy of the resource. The client would then immediately have access to the resource data without even needing to wait for a request and response. If the server has a newer copy of the resource than the cached copy, the resource would be immediately delivered to the client and the client would receive the update as soon as the HTTP response was received by the client. The fact that the client chose to subscribe to the resource indicates that the client code is prepared to handle updates. This behavior takes advantage of this fact to allow immediate access to cached data while waiting for a server copy of the data, which is treated as an update. Furthermore, if the cached copy is fresh, the server does not need to send a 304 response, as it can simply block the connection and wait for a future modification. In the meantime the client can happily continue with the cached fresh copy of the resource data, while listening for any updates from the server. This can provide a substantial improvement in performance of incrementally rendering data in applications, especially in the face of poor or broken network connections. This provides a capability reminiscent of that suggested by the stale-while-revalidated and stale-if-error headers used by Yahoo. A client can act like an offline client, immediately showing cached resource data until network response demonstrates otherwise. This provides a much more rapid and seamless approach to handle network uncertainty than waiting for a network problem before resorting to cached/offline resource handling.
Flexible Low or High Level Interaction
This API provides flexibility and means for developers to interact with Comet at various different levels. Developers could easily use this API to create their own low-level-customized high-speed Comet protocol since all the capabilities of HTTP can be controlled and accessed: method, request and response headers, request and response entities, and status codes. Bayeux could easily be implemented with this API. Developers could use the sendChunk method to create their own custom stream of messages, and directly parse responseText on incremental updates to do their own message partitioning. The API also allows developers to work at a higher level, simply issuing resource subscription requests with the subscribe property and delivering and receiving messages as HTTP messages. An important characteristic of HTTP/REST that is preserved by this API is that it does not force any inter-connection statefulness. By using the When-Modified-After header, subscriptions can be issued without requiring the server to maintain a session to remember subscriptions. An HTTP user agent should not force stateful interconnection session handling. Subscriptions are all local to an HTTP connection. When the connection is broken, a server may discard any subscription information related to that connection. This is a very important concept for utilizing shared-nothing (or at least shared-little) principles to easily create simple scalable servers. Developers are still free to create Comet communications that utilize stateful sessions when desired.
The When-Modified-After header is also advantageous in unreliable connection situations. If an application temporarily goes offline or if an underlying TCP connection is broken, the When-Modified-After header allows a client to easily resume a subscription from the last time of an update. To resume a subscription, the client simply sends a request with the When-Modified-After header set to the time of the last update. The server can simply compare the resource date with the When-Modified-After header date to determine if a resource needs to be sent. It does not need to keep individual event queues for each client in order to resume a connection.
Compatibility with Existing Capabilities
Even if my fantasy world of having commit privileges to all the browser code bases really did exist, adoption does not happen overnight. We would still be faced with dealing with existing browser implementations. However, this proposal for native Comet implementation using HTTP standards does not exclude current browsers from participation in the suggested Comet communication. Current browsers would not realize the performance benefits of client-delivered streaming, consistent server-delivered streaming handling, and cached until updated responses. However, all of the suggested communication techniques including message/http requests and responses and the When-Modified-After header are fully accessible with the existing capabilities of XMLHttpRequest. This means servers could easily deliver Comet communication without requiring separate protocols for newer implementations and existing implementations. Comet communication can remain consistent, with native implementations driving simple APIs and enjoying major performance benefits. Existing implementations can gracefully degrade, using JavaScript to emulate APIs, manually batching requests, and aborting and recreating HTTP connections in order to send new subscription requests and resume connections in browsers that do not support XMLHttpRequest interactive mode (IE). I am hoping to actually create a JavaScript implementation of this approach and make it available.
A native implementation that augmented these XMLHttpRequest capabilities would also be backwards compatible in behavior since all the new behaviors require opt-in (through sendChunk, addHTTPChunk, and subscribe).
Conclusion
With only a few simple XMLHttpRequest API additions, Comet communication could be realized with a native implementation that supports fast and efficient standards-based two-way asynchronous communication, with true server-delivered HTTP streaming and simple subscription requests, with the added benefit of client-delivered streaming and cached resource until updated capability. Developers could create Comet applications with a standard API without hacks. Communication could be standards-based, allowing current servers to easily implement the necessary features to handle communication.
Notes
To understand the When-Modified-After header, it is worth comparing it to the If-Modified-Since header. The behavior is similar. If the server’s resource is newer than the header’s date, the server immediately returns the server’s copy. When the resource matches or is older than the header’s date, the If-Modified-Since header says that the server should return a 304 Not Modified, whereas the When-Modified-After header says the server should wait until a modification occurs. The When-Modified-After header also suggests that when possible (when the client declares that it Accepts message/http with content negotiation) the connection should stay open indefinitely so as to receive multiple update responses.
Posted in COMET | Tagged: browser, COMET, XMLHttpRequest | Leave a Comment »







