75
Going Live! with Comet Simon Willison - http://simonwillison.net / SkillSwap Brighton, 11th June 2008 Header image: http://svn.xantus.org/shortbus/trunk/cometd-perl/html/

Going Live! with Comet

Embed Size (px)

DESCRIPTION

An introduction to Comet, presented at Brighton SkillSwap on the 11th of June 2008.

Citation preview

Page 1: Going Live! with Comet

Going Live! with Comet

Simon Willison - http://simonwillison.net/SkillSwap Brighton, 11th June 2008

Header image: http://svn.xantus.org/shortbus/trunk/cometd-perl/html/

Page 2: Going Live! with Comet
Page 3: Going Live! with Comet

Live data on the Web

• A new frontier for web apps

• Chat, everywhere - Meebo, Facebook, GChat...

• Twitter (well, it would be nice if it was live)

• Life-casting, live video

• Collaboration tools

• Push, not Pull

Page 5: Going Live! with Comet

Comet: any method that allows a web server to push events “live” to connected browsers

Page 6: Going Live! with Comet

A new name for a very old technique

• Also known as...

• HTTP push

• Server push

• Reverse Ajax

• Pushlets

• ...

Page 7: Going Live! with Comet

Coined by Alex Russell in 2006

Page 8: Going Live! with Comet

Deliberately named after a kitchen cleaner

Page 9: Going Live! with Comet

What can you do with it?

Page 10: Going Live! with Comet
Page 11: Going Live! with Comet
Page 12: Going Live! with Comet
Page 13: Going Live! with Comet
Page 14: Going Live! with Comet
Page 15: Going Live! with Comet
Page 16: Going Live! with Comet

Google Finance

Page 17: Going Live! with Comet
Page 18: Going Live! with Comet

Early Comet

Page 19: Going Live! with Comet
Page 20: Going Live! with Comet

Netscape 1.1, March 1995

Page 21: Going Live! with Comet

Netscape 1.1 new features

Page 22: Going Live! with Comet

Netscape 1.1 new features

• Tables

Page 23: Going Live! with Comet

Netscape 1.1 new features

• Tables

• Background images

Page 24: Going Live! with Comet

Netscape 1.1 new features

• Tables

• Background images

• “Dynamic Documents”

Page 25: Going Live! with Comet

Netscape 1.1 new features

• Tables

• Background images

• “Dynamic Documents”

• Client Pull

Page 26: Going Live! with Comet

Netscape 1.1 new features

• Tables

• Background images

• “Dynamic Documents”

• Client Pull

• Server Push

Page 27: Going Live! with Comet

Netscape 1.1 new features

• Tables

• Background images

• “Dynamic Documents”

• Client Pull

• Server Push

• Predates JavaScript, Internet Explorer and Flash

Page 28: Going Live! with Comet

Server Push, Client Pull

Page 29: Going Live! with Comet

“Client Pull”

<META HTTP-EQUIV="Refresh" CONTENT=1>

Page 30: Going Live! with Comet

“Server Push”Content-type: multipart/x-mixed-replace;boundary=XXooXX

--XXooXXContent-type: text/plain

Data for the first object.

--XXooXXContent-type: text/plain

Data for the second and last object.

--XXooXX--

Page 31: Going Live! with Comet
Page 32: Going Live! with Comet

http://zesty.ca/chat/ (1999)

Page 33: Going Live! with Comet

Modern Comet

Page 34: Going Live! with Comet

var xhr = new XMLHttpRequest();xhr.open('GET', '/comet', true);

xhr.onreadystatechange = function() { if (readyState == 3) { // Process xhr.responseText }};

Page 35: Going Live! with Comet

If only it werethat simple...

Page 36: Going Live! with Comet

An Epic Saga

Of geek v.s. browser

http://airminded.org/2007/05/25/the-movie-that-time-forgot/

Page 37: Going Live! with Comet

Problem #1

Page 38: Going Live! with Comet

Problem #1

Page 39: Going Live! with Comet

Problem #1

xhr.responseText isn’t available untilthe page has finished loading

Page 40: Going Live! with Comet

A hidden iframe

• Add a hidden iframe pointing at a streaming page

• Send down chunks of <script> blocks, which the browser will execute as part of progressive rendering

• Add 1KB of junk at the start to trigger progressive rendering in IE

(The forever frame technique)

Page 41: Going Live! with Comet

Problem #2

The throbber!

Page 42: Going Live! with Comet

Problem #2

The throbber!

Problem #3 The click!

Page 43: Going Live! with Comet

Solved for GChatvar htmlfile = new ActiveXObject('htmlfile');

• An undocumented ActiveX extension

• Create an "htmlfile" instance

• Create an iframe inside it

• Set up some cross-frame scripting hooks

• Run comet using the iframe

• No clicks! No throbber!

Page 44: Going Live! with Comet

Huh?

Confuse IE with enough nested iframes and it forgets to click

Page 45: Going Live! with Comet

Problem #4

Page 46: Going Live! with Comet

Problem #4

Proxies!

Page 47: Going Live! with Comet

Long polling

• Make a request (iframe, XHR or even a <script> tag)

• Server pretends to be processing it really slowly...

• An event occurs; the server finally returns the response

• The browser starts a new request straight away

Page 48: Going Live! with Comet

Problem #5

The two connection limit

Page 49: Going Live! with Comet

• mysite.com - regular site

• comet.mysite.com - comet server

• Cross-domain communication is easy - just add another iframe and set document.domain to enable cross-frame scripting

• (Then solve the resulting browser history problems with a few more iframes)

• Facebook go a step further and use incrementing subdomains for every request

Page 50: Going Live! with Comet

• mysite.com - regular site

• comet.mysite.com - comet server

• Cross-domain communication is easy - just add another iframe and set document.domain to enable cross-frame scripting

• (Then solve the resulting browser history problems with a few more iframes)

• Facebook go a step further and use incrementing subdomains for every request

Page 51: Going Live! with Comet

• mysite.com - regular site

• comet.mysite.com - comet server

• Cross-domain communication is easy - just add another iframe and set document.domain to enable cross-frame scripting

• (Then solve the resulting browser history problems with a few more iframes)

• Facebook go a step further and use incrementing subdomains for every request

Page 52: Going Live! with Comet

And if all else fails...

Page 53: Going Live! with Comet

Fall back to pollingSoundAndFury http://www.flickr.com/photos/sound_and_fury/2166186492/

Are we there yet?Are we there yet?Are we there yet?

Page 54: Going Live! with Comet

Pterodactyls win!

Page 55: Going Live! with Comet

Key techniques

• Streaming (ideal)

• XMLHttpRequest

• Forever frame (for IE)

• Long polling (works through proxies)

• Polling (if all else fails)

Page 56: Going Live! with Comet

Future Comet

Page 57: Going Live! with Comet

<event-source src="/comet">

Content-Type: application/x-dom-event-stream

Event: server-timedata: [time on the server]

HTML 5 event-source

Support added in Opera 9.5

http://www.whatwg.org/specs/web-apps/current-work/#event-source

Page 58: Going Live! with Comet

Google Gears 0.2

Page 59: Going Live! with Comet

“Wow, client-side Comet sucks”...

that’s not the half of it

Page 60: Going Live! with Comet

Scaling the serverhttp://flickr.com/photos/adrianblack/254968866/ craig1black

Page 61: Going Live! with Comet

• Comet requires potentially tens of thousands of simultaneous HTTP connections

• Apache and other mainstream servers are designed to handle a single request as quickly as possible

• Requests are generally served by a worker process or thread

• This absolutely will not scale to Comet

Page 62: Going Live! with Comet

• Alternative architecture designed to handle thousands of simultaneous connections

• Twisted (Python)

• Jetty (Java)

• Perlbal

• Orbited

• Meteor

• Facebook used MochiWeb (in Erlang)

Event-based IO

Page 63: Going Live! with Comet

Bayeaux

Page 64: Going Live! with Comet

Bayeaux

• Bayeaux is a protocol for Comet

• Any Bayeaux client can talk to any Bayeaux server

• The protocol is based on clients publishing and subscribing to channels

• Data is encoded using JSON

• Clients can create a permanent connection using a handshake, or send simple one-off messages

Page 65: Going Live! with Comet

Dumb Comet servers

• The principle advantage of Bayeaux is that your Comet server can be stupid - it doesn’t need any application logic, it just needs to route messages around

• It’s a black box which you simply drop in to your architecture

• This means your application logic can stay on your favourite platform

Page 66: Going Live! with Comet

Cometd

• Cometd (Comet Daemon) is an umbrella project for a number of Bayeaux implementations

• cometd-python (in Twisted)

• cometd-perl (also a Perlbal plugin)

• cometd-java (on Jetty)

• dojox.cometd (JavaScript client)

• http://cometd.com/

Page 67: Going Live! with Comet

So despite all of that... Comet applications

are easy to build

Page 68: Going Live! with Comet

How to build a Comet application (in 5 minutes)

Page 69: Going Live! with Comet

Set up Jetty

• Download and unzip Jetty-6.1 from www.mortbay.org

• Install Maven from http://maven.apache.org/

• cd jetty-6.1.6/contrib/cometd/demo/

• mvn jetty:run

• Browse to http://localhost:8080/

• Mess around with the JS in src/main/webapp/examples/

Page 70: Going Live! with Comet

dojox.cometd

dojo.addOnLoad(function() { dojox.cometd.init("http://127.0.0.1:8080/cometd"); dojox.cometd.subscribe("/mychannel", function(comet) { alert(comet.data); // a JSON object });

dojo.byId('send').onclick = function() { dojox.cometd.publish("/mychannel", { 'msg': "A message sent by Comet" }); return false; };});

Page 71: Going Live! with Comet

dojox.cometd

dojo.addOnLoad(function() { dojox.cometd.init("http://127.0.0.1:8080/cometd"); dojox.cometd.subscribe("/mychannel", function(comet) { alert(comet.data); // a JSON object });

dojo.byId('send').onclick = function() { dojox.cometd.publish("/mychannel", { 'msg': "A message sent by Comet" }); return false; };});

Page 72: Going Live! with Comet

A slideshow in 5 lines of code

<script type="text/javascript">dojo.require("dojox.cometd");jQuery(function($) { dojox.cometd.init("http://127.0.0.1:8080/cometd"); dojox.cometd.subscribe("/slideshow/change", function(comet) { $('#currentSlide').attr('src', comet.data.src); });});</script>

Page 73: Going Live! with Comet

Conclusions

• Comet is possible, therefore it’s inevitable

• It requires hacks, but they’re reasonably well abstracted and understood

• Bayeaux and Cometd abstract away the nastiness and make Comet accessible to sane developers

Page 75: Going Live! with Comet

Thank you