<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: comet</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/comet.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2011-01-10T11:57:00+00:00</updated><author><name>Simon Willison</name></author><entry><title>Why does Facebook chat use subdomains so aggressively?</title><link href="https://simonwillison.net/2011/Jan/10/why-does-facebook-chat/#atom-tag" rel="alternate"/><published>2011-01-10T11:57:00+00:00</published><updated>2011-01-10T11:57:00+00:00</updated><id>https://simonwillison.net/2011/Jan/10/why-does-facebook-chat/#atom-tag</id><summary type="html">
    &lt;p&gt;&lt;em&gt;My answer to &lt;a href="https://www.quora.com/Why-does-Facebook-chat-use-subdomains-so-aggressively/answer/Simon-Willison"&gt;Why does Facebook chat use subdomains so aggressively?&lt;/a&gt; on Quora&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Probably because it involves long-running connections. Browsers have a limit on the number of connections you can have open to the same domain at the same time (I think it's 8 in most browsers these days). If Facebook chat opened a connection to &lt;span&gt;&lt;a href="http://www.facebook.com"&gt;www.facebook.com&lt;/a&gt;&lt;/span&gt; and you opened up 8 Facebook windows you would no longer be able to navigate to any more Facebook pages, since all 8 connections would be taken up by the long lived chat connections. By connecting to a different subdomain for each connection this problem can be avoided.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="comet"/><category term="javascript"/><category term="quora"/></entry><entry><title>What is the history of Django?</title><link href="https://simonwillison.net/2010/Aug/24/quora/#atom-tag" rel="alternate"/><published>2010-08-24T17:31:00+00:00</published><updated>2010-08-24T17:31:00+00:00</updated><id>https://simonwillison.net/2010/Aug/24/quora/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.quora.com/What-is-the-history-of-Python-Django"&gt;What is the history of Django?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I’ve been playing with Quora—it’s a really neat twist on the question-and-answer format, which makes great use of friends, followers and topics and has some very neat live update stuff going on (using Comet on top of Tornado). I just posted quite a long answer to a question about the history of Django.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/history"&gt;history&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tornado"&gt;tornado&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/qna"&gt;qna&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="django"/><category term="history"/><category term="tornado"/><category term="quora"/><category term="recovered"/><category term="qna"/></entry><entry><title>Hookbox</title><link href="https://simonwillison.net/2010/Jul/29/hookbox/#atom-tag" rel="alternate"/><published>2010-07-29T09:48:00+00:00</published><updated>2010-07-29T09:48:00+00:00</updated><id>https://simonwillison.net/2010/Jul/29/hookbox/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://hookbox.org/"&gt;Hookbox&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
For most web projects, I believe implementing any real-time comet features on a separate stack from the rest of the application makes sense—keep using Rails, Django or PHP for the bulk of the application logic, and offload any WebSocket or Comet requests to a separate stack built on top of something like Node.js, Twisted, EventMachine or Jetty. Hookbox is the best example of that philosophy I’ve yet seen—it’s a Comet server that makes WebHook requests back to your regular application stack to check if a user has permission to publish or subscribe to a given channel. “The key insight is that all application development with hookbox happens either in JavaScript or in the native language of the web application itself”.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://cometdaily.com/2010/07/26/a-fast-introduction-to-hookbox/"&gt;Comet Daily&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/michael-carter"&gt;michael-carter&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/php"&gt;php&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rails"&gt;rails&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webhooks"&gt;webhooks&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hookbox"&gt;hookbox&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="django"/><category term="javascript"/><category term="michael-carter"/><category term="php"/><category term="rails"/><category term="webhooks"/><category term="recovered"/><category term="hookbox"/></entry><entry><title>App Engine at Google I/O 2010</title><link href="https://simonwillison.net/2010/May/20/appengine/#atom-tag" rel="alternate"/><published>2010-05-20T15:30:00+00:00</published><updated>2010-05-20T15:30:00+00:00</updated><id>https://simonwillison.net/2010/May/20/appengine/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://googleappengine.blogspot.com/2010/05/app-engine-at-google-io-2010.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A GoogleAppEngineBlog %28Google App Engine Blog%29"&gt;App Engine at Google I/O 2010&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
OpenID and OAuth are now baked in to the AppEngine users API. They’re also demoing two very exciting new features—a mapper API for doing map/reduce style queries against the data store, and a Channel API for building comet applications.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-app-engine"&gt;google-app-engine&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mapreduce"&gt;mapreduce&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/oauth"&gt;oauth&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openid"&gt;openid&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-io"&gt;google-io&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="google"/><category term="google-app-engine"/><category term="mapreduce"/><category term="oauth"/><category term="openid"/><category term="google-io"/><category term="recovered"/></entry><entry><title>Realtime Election Tweets</title><link href="https://simonwillison.net/2010/May/6/realtime/#atom-tag" rel="alternate"/><published>2010-05-06T21:20:00+00:00</published><updated>2010-05-06T21:20:00+00:00</updated><id>https://simonwillison.net/2010/May/6/realtime/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://jay.gooby.org/post/realtime-election-tweets"&gt;Realtime Election Tweets&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Jay Caines-Gooby’s realtime election tweet service, using Node.js, nginx and WebSocket with a Flash fallback.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flash"&gt;flash&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nodejs"&gt;nodejs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/realtime"&gt;realtime&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/twitter"&gt;twitter&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/election"&gt;election&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jay-caines-gooby"&gt;jay-caines-gooby&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="flash"/><category term="javascript"/><category term="nodejs"/><category term="realtime"/><category term="twitter"/><category term="websockets"/><category term="recovered"/><category term="election"/><category term="jay-caines-gooby"/></entry><entry><title>Lou's Pseudo 3d Page</title><link href="https://simonwillison.net/2010/Feb/8/pseudo/#atom-tag" rel="alternate"/><published>2010-02-08T11:21:18+00:00</published><updated>2010-02-08T11:21:18+00:00</updated><id>https://simonwillison.net/2010/Feb/8/pseudo/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.gorenfeld.net/lou/pseudo/"&gt;Lou&amp;#x27;s Pseudo 3d Page&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Spectacularly detailed exploration of the road graphics used in racing games prior to true 3D. This is a potential gold mine for anyone looking for a fun project to try out with canvas. Bonus points for comet integration—I’m still looking forward to the first real-time multiplayer game in the browser using comet and canvas.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/3d"&gt;3d&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/canvas"&gt;canvas&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/game-design"&gt;game-design&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/graphics"&gt;graphics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/html5"&gt;html5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;&lt;/p&gt;



</summary><category term="3d"/><category term="canvas"/><category term="comet"/><category term="game-design"/><category term="graphics"/><category term="html5"/><category term="javascript"/></entry><entry><title>Comet (long polling) for all browsers using ScriptCommunicator</title><link href="https://simonwillison.net/2010/Feb/3/scriptcommunicator/#atom-tag" rel="alternate"/><published>2010-02-03T00:37:34+00:00</published><updated>2010-02-03T00:37:34+00:00</updated><id>https://simonwillison.net/2010/Feb/3/scriptcommunicator/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://amix.dk/blog/post/19489#ScriptCommunicator-implementing-comet-long-polling-for-all-browse"&gt;Comet (long polling) for all browsers using ScriptCommunicator&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
More Comet from the Plurk team: 80 lines of dependency free JavaScript implementing long polling using script tags (hence working cross-domain) across IE6+, Firefox, WebKit and Opera. The clever bit is the code to detect loading errors. It doesn’t try to fix the infinite loading indicator problem—is that still a cromulent usability concern?


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/long-polling"&gt;long-polling&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/plurk"&gt;plurk&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/usability"&gt;usability&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="javascript"/><category term="long-polling"/><category term="plurk"/><category term="usability"/></entry><entry><title>Plurk: Instant conversations using Comet</title><link href="https://simonwillison.net/2010/Feb/1/plurk/#atom-tag" rel="alternate"/><published>2010-02-01T10:13:14+00:00</published><updated>2010-02-01T10:13:14+00:00</updated><id>https://simonwillison.net/2010/Feb/1/plurk/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://amix.dk/blog/post/19490"&gt;Plurk: Instant conversations using Comet&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Plurk’s comet implementation sounds pretty amazing. They’re using a single quad-core server with 32GB of RAM running 8 Node.js instances to serve long-polled comet to 100,000+ simultaneous users. They switched to Node from Java JBoss/Netty and found the new solution used 10 times less memory.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://news.ycombinator.com/item?id=1088699"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/java"&gt;java&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jboss"&gt;jboss&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/netty"&gt;netty&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nodejs"&gt;nodejs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/plurk"&gt;plurk&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="java"/><category term="javascript"/><category term="jboss"/><category term="netty"/><category term="nodejs"/><category term="plurk"/></entry><entry><title>Web Sockets in Tornado</title><link href="https://simonwillison.net/2009/Dec/31/websockets/#atom-tag" rel="alternate"/><published>2009-12-31T11:54:48+00:00</published><updated>2009-12-31T11:54:48+00:00</updated><id>https://simonwillison.net/2009/Dec/31/websockets/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://bret.appspot.com/entry/web-sockets-in-tornado"&gt;Web Sockets in Tornado&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Bret Taylor has a simple class making it trivial to experiment with the Web Sockets protocol (now shipping in Chrome) using the scalable Tornado application server. He also raises the million dollar question: what will existing load balancers and proxies make of the new protocol?


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/bret-taylor"&gt;bret-taylor&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chrome"&gt;chrome&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tornado"&gt;tornado&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;&lt;/p&gt;



</summary><category term="bret-taylor"/><category term="chrome"/><category term="comet"/><category term="python"/><category term="tornado"/><category term="websockets"/></entry><entry><title>Real time online activity monitor example with node.js and WebSocket</title><link href="https://simonwillison.net/2009/Dec/8/activity/#atom-tag" rel="alternate"/><published>2009-12-08T23:07:36+00:00</published><updated>2009-12-08T23:07:36+00:00</updated><id>https://simonwillison.net/2009/Dec/8/activity/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://blog.new-bamboo.co.uk/2009/12/7/real-time-online-activity-monitor-example-with-node-js-and-websocket"&gt;Real time online activity monitor example with node.js and WebSocket&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
A neat exploration of Node.js—first hooking a “tail -f” process up to an HTTP push stream, then combining that with HTML 5 WebSockets to achieve reliable streaming.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/html5"&gt;html5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nodejs"&gt;nodejs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="html5"/><category term="http"/><category term="javascript"/><category term="nodejs"/><category term="websockets"/></entry><entry><title>Node.js is genuinely exciting</title><link href="https://simonwillison.net/2009/Nov/23/node/#atom-tag" rel="alternate"/><published>2009-11-23T12:50:22+00:00</published><updated>2009-11-23T12:50:22+00:00</updated><id>https://simonwillison.net/2009/Nov/23/node/#atom-tag</id><summary type="html">
    &lt;p&gt;I gave a talk on Friday at &lt;a href="http://2009.full-frontal.org/"&gt;Full Frontal&lt;/a&gt;, a new one day JavaScript conference in my home town of Brighton. I ended up throwing away my intended topic (JSONP, APIs and cross-domain security) three days before the event in favour of a technology which first crossed my radar &lt;a href="http://simonwillison.net/2009/Nov/9/node/"&gt;less than two weeks ago&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That technology is Ryan Dahl's &lt;a href="http://nodejs.org/"&gt;Node&lt;/a&gt;. It's the most exciting new project I've come across in quite a while.&lt;/p&gt;

&lt;p&gt;At first glance, Node looks like yet another take on the idea of server-side JavaScript, but it's a lot more interesting than that. It builds on JavaScript's excellent support for event-based programming and uses it to create something that truly plays to the strengths of the language.&lt;/p&gt;

&lt;p&gt;Node describes itself as "evented I/O for V8 javascript". It's a toolkit for writing extremely high performance non-blocking event driven network servers in JavaScript. Think similar to &lt;a href="http://twistedmatrix.com/"&gt;Twisted&lt;/a&gt; or &lt;a href="http://rubyeventmachine.com/"&gt;EventMachine&lt;/a&gt; but for JavaScript instead of Python or Ruby.&lt;/p&gt;

&lt;h4&gt;Evented I/O?&lt;/h4&gt;

&lt;p&gt;As I discussed in my talk, event driven servers are a powerful alternative to the threading / blocking mechanism used by most popular server-side programming frameworks. Typical frameworks can only handle a small number of requests simultaneously, dictated by the number of server threads or processes available. Long-running operations can tie up one of those threads - enough long running operations at once and the server runs out of available threads and becomes unresponsive. For large amounts of traffic, each request must be handled as quickly as possible to free the thread up to deal with the next in line.&lt;/p&gt;

&lt;p&gt;This makes certain functionality extremely difficult to support. Examples include handling large file uploads, combining resources from multiple backend web APIs (which themselves can take an unpredictable amount of time to respond) or providing comet functionality by holding open the connection until a new event becomes available.&lt;/p&gt;

&lt;p&gt;Event driven programming takes advantage of the fact that network servers spend most of their time waiting for I/O operations to complete. Operations against in-memory data are incredibly fast, but anything that involves talking to the filesystem or over a network inevitably involves waiting around for a response.&lt;/p&gt;

&lt;p&gt;With Twisted, EventMachine and Node, the solution lies in specifying I/O operations in conjunction with callbacks. A single event loop rapidly switches between a list of tasks, firing off I/O operations and then moving on to service the next request. When the I/O returns, execution of that particular request is picked up again.&lt;/p&gt;

&lt;p&gt;(In the talk, I attempted to illustrate this with a questionable metaphor involving &lt;a href="http://www.slideshare.net/simon/evented-io-based-web-servers-explained-using-bunnies"&gt;hamsters, bunnies and a hyperactive squid&lt;/a&gt;).&lt;/p&gt;

&lt;iframe src="https://www.slideshare.net/slideshow/embed_code/key/B8ICSKJbZ2cBHw?startSlide=1" width="597" height="486" frameborder="0"   marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px;   margin-bottom:5px;max-width: 100%;" allowfullscreen="allowfullscreen"&gt;
&lt;/iframe&gt;

&lt;h4&gt;What makes Node exciting?&lt;/h4&gt;

&lt;p&gt;If systems like this already exist, what's so exciting about Node? Quite a few things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;JavaScript is extremely well suited to programming with callbacks&lt;/strong&gt;. Its anonymous function syntax and closure support is perfect for defining inline callbacks, and client-side development in general uses event-based programming as a matter of course: run this function when the user clicks here / when the Ajax response returns / when the page loads. JavaScript programmers already understand how to build software in this way.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Node represents a clean slate&lt;/strong&gt;. Twisted and EventMachine are hampered by the existence of a large number of blocking libraries for their respective languages. Part of the difficulty in learning those technologies is understanding which Python or Ruby libraries you can use and which ones you have to avoid. Node creator Ryan Dahl has a stated aim for Node to never provide a blocking API - even filesystem access and DNS lookups are catered for with non-blocking callback based APIs. This makes it much, much harder to screw things up.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Node is small&lt;/strong&gt;. I read through the &lt;a href="http://nodejs.org/api.html"&gt;API documentation&lt;/a&gt; in around half an hour and felt like I had a pretty comprehensive idea of what Node does and how I would achieve things with it.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Node is fast&lt;/strong&gt;. V8 is the fast and keeps getting faster. Node's event loop uses Marc Lehmann's highly regarded &lt;a href="http://software.schmorp.de/pkg/libev.html"&gt;libev&lt;/a&gt; and &lt;a href="http://software.schmorp.de/pkg/libeio.html"&gt;libeio&lt;/a&gt; libraries. Ryan Dahl is himself something of a speed demon - he just replaced Node's HTTP parser implementation (already pretty speedy due to it's Ragel / Mongrel heritage) with a &lt;a href="http://four.livejournal.com/1033160.html"&gt;hand-tuned C implementation&lt;/a&gt; with some impressive characteristics.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Easy to get started&lt;/strong&gt;. Node ships with all of its dependencies, and compiles cleanly on Snow Leopard out of the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With both my JavaScript and server-side hats on, Node just feels right. The APIs make sense, it fits a clear niche and despite its youth (the project started in February) everything feels solid and well constructed. The rapidly growing community is further indication that Ryan is on to something great here.&lt;/p&gt;

&lt;h4&gt;What does Node look like?&lt;/h4&gt;

&lt;p&gt;Here's how to get Hello World running in Node in 7 easy steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;samp&gt;git clone git://github.com/ry/node.git&lt;/samp&gt; (or download and extract &lt;a href="http://github.com/ry/node/archives/master" title="Download ry/node from GitHub"&gt;a tarball&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;samp&gt;./configure&lt;/samp&gt;&lt;/li&gt;
  &lt;li&gt;&lt;samp&gt;make&lt;/samp&gt; (takes a while, it needs to compile V8 as well)&lt;/li&gt;
  &lt;li&gt;&lt;samp&gt;sudo make install&lt;/samp&gt;&lt;/li&gt;
  &lt;li&gt;Save the below code as &lt;samp&gt;helloworld.js&lt;/samp&gt;&lt;/li&gt;
  &lt;li&gt;&lt;samp&gt;node helloworld.js&lt;/samp&gt;&lt;/li&gt;
  &lt;li&gt;Visit &lt;samp&gt;http://localhost:8080/&lt;/samp&gt; in your browser&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's helloworld.js:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var sys = require('sys'), 
  http = require('http');

http.createServer(function(req, res) {
  res.sendHeader(200, {'Content-Type': 'text/html'});
  res.sendBody('&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;');
  res.finish();
}).listen(8080);

sys.puts('Server running at http://127.0.0.1:8080/');
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you have Apache Bench installed, try running &lt;samp&gt;ab -n 1000 -c 100 'http://127.0.0.1:8080/'&lt;/samp&gt; to test it with 1000 requests using 100 concurrent connections. On my MacBook Pro I get 3374 requests a second.&lt;/p&gt;

&lt;p&gt;So Node is fast - but where it really shines is concurrency with long running requests. Alter the helloworld.js server definition to look like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;http.createServer(function(req, res) {
  setTimeout(function() {
    res.sendHeader(200, {'Content-Type': 'text/html'});
    res.sendBody('&amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;');
    res.finish();
  }, 2000);
}).listen(8080);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We're using &lt;samp&gt;setTimeout&lt;/samp&gt; to introduce an artificial two second delay to each request. Run the benchmark again - I get 49.68 requests a second, with every single request taking between 2012 and 2022 ms. With a two second delay, the best possible performance for 1000 requests 100 at a time is  &lt;em&gt;1000 requests / (1000 / 100) * 2 seconds = 50 requests a second&lt;/em&gt;. Node hits it pretty much bang on the nose.&lt;/p&gt;

&lt;p&gt;The most important line in the above examples is &lt;code&gt;res.finish()&lt;/code&gt;. This is the mechanism Node provides for explicitly signalling that a request has been fully processed and should be returned to the browser. By making it explicit, Node makes it easy to implement comet patterns like long polling and streaming responses - stuff that is decidedly non trivial in most server-side frameworks.&lt;/p&gt;

&lt;h4&gt;djangode&lt;/h4&gt;

&lt;p&gt;Node's core APIs are pretty low level - it has HTTP client and server libraries, DNS handling, asynchronous file I/O etc, but it doesn't give you much in the way of high level web framework APIs. Unsurprisingly, this has lead to a cambrian explosion of lightweight web frameworks based on top of Node - the &lt;a href="http://wiki.github.com/ry/node"&gt;projects using node page&lt;/a&gt; lists a bunch of them. Rolling a framework is a great way of learning a low-level API, so I've thrown together my own - &lt;a href="http://github.com/simonw/djangode"&gt;djangode&lt;/a&gt; - which brings Django's regex-based URL handling to Node along with a few handy utility functions. Here's a simple djangode application:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var dj = require('./djangode');

var app = dj.makeApp([
  ['^/$', function(req, res) {
    dj.respond(res, 'Homepage');
  }],
  ['^/other$', function(req, res) {
    dj.respond(res, 'Other page');
  }],
  ['^/page/(\\d+)$', function(req, res, page) {
    dj.respond(res, 'Page ' + page);
  }]
]);
dj.serve(app, 8008);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;djangode is currently a throwaway prototype, but I'll probably be extending it with extra functionality as I explore more Node related ideas.&lt;/p&gt;

&lt;h4&gt;nodecast&lt;/h4&gt;

&lt;p&gt;My main demo in the Full Frontal talk was nodecast, an extremely simple broadcast-oriented comet application. Broadcast is my favourite "hello world" example for comet because it's both simpler than chat and more realistic - I've been involved in plenty of projects that could benefit from being able to broadcast events to their audience, but few that needed an interactive chat room.&lt;/p&gt;

&lt;p&gt;The source code for the version I demoed can be found on GitHub in &lt;a href="http://github.com/simonw/nodecast/tree/no-redis"&gt;the no-redis branch&lt;/a&gt;. It's a very simple application - the client-side JavaScript simply uses jQuery's getJSON method to perform long-polling against a simple URL endpoint:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;function fetchLatest() {
  $.getJSON('/wait?id=' + last_seen, function(d) {
    $.each(d, function() {
      last_seen = parseInt(this.id, 10) + 1;
      ul.prepend($('&amp;lt;li&amp;gt;&amp;lt;/li&amp;gt;').text(this.text));
    });
    fetchLatest();
  });
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Doing this recursively is probably a bad idea since it will eventually blow the browser's JavaScript stack, but it works OK for the demo.&lt;/p&gt;

&lt;p&gt;The more interesting part is the server-side &lt;samp&gt;/wait&lt;/samp&gt; URL which is being polled. Here's the relevant Node/djangode code:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var message_queue = new process.EventEmitter();

var app = dj.makeApp([
  // ...
  ['^/wait$', function(req, res) {
    var id = req.uri.params.id || 0;
    var messages = getMessagesSince(id);
    if (messages.length) {
      dj.respond(res, JSON.stringify(messages), 'text/plain');
    } else {
      // Wait for the next message
      var listener = message_queue.addListener('message', function() {
        dj.respond(res, 
          JSON.stringify(getMessagesSince(id)), 'text/plain'
        );
        message_queue.removeListener('message', listener);
        clearTimeout(timeout);
      });
      var timeout = setTimeout(function() {
        message_queue.removeListener('message', listener);
        dj.respond(res, JSON.stringify([]), 'text/plain');
      }, 10000);
    }
  }]
  // ...
]);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The wait endpoint checks for new messages and, if any exist, returns immediately. If there are no new messages it does two things: it hooks up a listener on the &lt;samp&gt;message_queue&lt;/samp&gt; EventEmitter (Node's equivalent of jQuery/YUI/Prototype's custom events) which will respond and end the request when a new message becomes available, and also sets a timeout that will cancel the listener and end the request after 10 seconds. This ensures that long polls don't go on too long and potentially cause problems - as far as the browser is concerned it's just talking to a JSON resource which takes up to ten seconds to load.&lt;/p&gt;

&lt;p&gt;When a message does become available, calling &lt;samp&gt;message_queue.emit('message')&lt;/samp&gt; will cause all waiting requests to respond with the latest set of messages.&lt;/p&gt;

&lt;h4&gt;Talking to databases&lt;/h4&gt;

&lt;p&gt;nodecast keeps track of messages using an in-memory JavaScript array, which works fine until you restart the server and lose everything. How do you implement persistent storage?&lt;/p&gt;

&lt;p&gt;For the moment, the easiest answer lies with the NoSQL ecosystem. Node's focus on non-blocking I/O makes it hard (but not impossible) to hook it up to regular database client libraries. Instead, it strongly favours databases that speak simple protocols over a TCP/IP socket - or even better, databases that communicate over HTTP. So far I've tried using CouchDB (with &lt;a href="http://github.com/sixtus/node-couch"&gt;node-couch&lt;/a&gt;) and redis (with &lt;a href="http://github.com/fictorial/redis-node-client"&gt;redis-node-client&lt;/a&gt;), and both worked extremely well. nodecast &lt;a href="http://github.com/simonw/nodecast"&gt;trunk&lt;/a&gt; now uses redis to store the message queue, and provides a nice example of working with a callback-based non-blocking database interface:&lt;/p&gt;

&lt;pre&gt;&lt;code class="javascript"&gt;var db = redis.create_client();
var REDIS_KEY = 'nodecast-queue';

function addMessage(msg, callback) {
  db.llen(REDIS_KEY, function(i) {
    msg.id = i; // ID is set to the queue length
    db.rpush(REDIS_KEY, JSON.stringify(msg), function() {
      message_queue.emit('message', msg);
      callback(msg);
    });
  });
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Relational databases are coming to Node. Ryan has a &lt;a href="http://github.com/ry/node_postgres"&gt;PostgreSQL adapter&lt;/a&gt; in the works, thanks to that database already featuring a mature non-blocking client library. MySQL will be a bit tougher - Node will need to grow a separate thread pool to integrate with the official client libs - but you can talk to MySQL right now by dropping in &lt;a href="https://open.nytimes.com/introducing-dbslayer-64d7168a143f"&gt;DBSlayer&lt;/a&gt; from the NY Times which provides an HTTP interface to a pool of MySQL servers.&lt;/p&gt;

&lt;h4&gt;Mixed environments&lt;/h4&gt;

&lt;p&gt;I don't see myself switching all of my server-side development over to JavaScript, but Node has definitely earned a place in my toolbox. It shouldn't be at all hard to mix Node in to an existing server-side environment - either by running both behind a single HTTP proxy (being event-based itself, &lt;a href="http://nginx.net/"&gt;nginx&lt;/a&gt; would be an obvious fit) or by putting Node applications on a separate subdomain. Node is a tempting option for anything involving comet, file uploads or even just mashing together potentially slow loading web APIs. Expect to hear a lot more about it in the future.&lt;/p&gt;

&lt;h4&gt;Further reading&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://s3.amazonaws.com/four.livejournal/20091117/jsconf.pdf"&gt;Ryan's JSConf.eu presentation&lt;/a&gt; is the best discussion I've seen anywhere of the design philosophy behind Node.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://nodejs.org/api.html"&gt;Node's API documentation&lt;/a&gt; is essential reading.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://debuggable.com/posts/streaming-file-uploads-with-node-js:4ac094b2-b6c8-4a7f-bd07-28accbdd56cb"&gt;Streaming file uploads with node.js&lt;/a&gt; illustrates how well suited Node is to accepting large file uploads.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://groups.google.com/group/nodejs"&gt;The nodejs Google Group&lt;/a&gt; is the hub of the Node community.&lt;/li&gt;
&lt;/ul&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/couchdb"&gt;couchdb&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/eventio"&gt;eventio&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nodejs"&gt;nodejs&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nosql"&gt;nosql&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/redis"&gt;redis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ryan-dahl"&gt;ryan-dahl&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/my-talks"&gt;my-talks&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tornado"&gt;tornado&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/twisted"&gt;twisted&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/v8"&gt;v8&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/highlights"&gt;highlights&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/annotated-talks"&gt;annotated-talks&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="async"/><category term="comet"/><category term="couchdb"/><category term="eventio"/><category term="http"/><category term="javascript"/><category term="nodejs"/><category term="nosql"/><category term="redis"/><category term="ryan-dahl"/><category term="my-talks"/><category term="tornado"/><category term="twisted"/><category term="v8"/><category term="highlights"/><category term="annotated-talks"/></entry><entry><title>SPDY: The Web, Only Faster</title><link href="https://simonwillison.net/2009/Nov/13/spdy/#atom-tag" rel="alternate"/><published>2009-11-13T13:00:08+00:00</published><updated>2009-11-13T13:00:08+00:00</updated><id>https://simonwillison.net/2009/Nov/13/spdy/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://alex.dojotoolkit.org/2009/11/spdy-the-web-only-faster/"&gt;SPDY: The Web, Only Faster&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Alex Russell explains the benefits of Google’s SPDF proposal (a protocol that upgrades HTTP)—including header compression, multiplexing, the ability to send additional resources such as images and stylesheets down without needing the data:uri hack and Comet support built in to the core assumptions of the protocol.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/alex-russell"&gt;alex-russell&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/compression"&gt;compression&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/datauri"&gt;datauri&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/spdy"&gt;spdy&lt;/a&gt;&lt;/p&gt;



</summary><category term="alex-russell"/><category term="comet"/><category term="compression"/><category term="datauri"/><category term="google"/><category term="http"/><category term="spdy"/></entry><entry><title>nginx_http_push_module</title><link href="https://simonwillison.net/2009/Oct/17/push/#atom-tag" rel="alternate"/><published>2009-10-17T16:48:31+00:00</published><updated>2009-10-17T16:48:31+00:00</updated><id>https://simonwillison.net/2009/Oct/17/push/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://github.com/slact/nginx_http_push_module"&gt;nginx_http_push_module&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
More clever design with webhooks—here’s an nginx module that provides a comet endpoint URL which will hang until a back end process POSTs to another URL on the same server. This makes it much easier to build asynchronous comet apps using regular synchronous web frameworks such as Django, PHP and Rails.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nginx"&gt;nginx&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/php"&gt;php&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/rails"&gt;rails&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webhooks"&gt;webhooks&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="django"/><category term="nginx"/><category term="php"/><category term="rails"/><category term="webhooks"/></entry><entry><title>Diesel</title><link href="https://simonwillison.net/2009/Sep/23/diesel/#atom-tag" rel="alternate"/><published>2009-09-23T17:15:42+00:00</published><updated>2009-09-23T17:15:42+00:00</updated><id>https://simonwillison.net/2009/Sep/23/diesel/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://dieselweb.org/lib/"&gt;Diesel&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Yet Another Asynchronous Python Comet Library, of interest because this is the first one I’ve seen that uses Python’s generator coroutines, taking advantage of the return value of the yield statement to feed messages in to a generator function. Currently only works on Python 2.6 on Linux due to a dependency on 2.6’s epoll support.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/diesel"&gt;diesel&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generators"&gt;generators&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;&lt;/p&gt;



</summary><category term="async"/><category term="comet"/><category term="diesel"/><category term="generators"/><category term="python"/></entry><entry><title>Tornado Web Server</title><link href="https://simonwillison.net/2009/Sep/10/tornado/#atom-tag" rel="alternate"/><published>2009-09-10T21:32:57+00:00</published><updated>2009-09-10T21:32:57+00:00</updated><id>https://simonwillison.net/2009/Sep/10/tornado/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.tornadoweb.org/"&gt;Tornado Web Server&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
An extremely exciting addition to the Python web landscape, Tornado is the open sourced version of FriendFeed’s custom web stack. It’s a non-blocking (epoll) Python web server designed for handling thousands of simultaneous connections, perfect for building Comet applications. The web framework is cosmetically similar to web.py or App Engine’s webapp but has decorators for writing asynchronous request handlers. The template language uses Django-style syntax but allows you to use full Python expressions. FriendFeed have benchmarked it handling 8,000 requests a second running as four load-balanced processes on a 4 core server.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://bret.appspot.com/entry/tornado-web-server"&gt;Bret Taylor&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/bret-taylor"&gt;bret-taylor&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/epoll"&gt;epoll&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/friendfeed"&gt;friendfeed&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-app-engine"&gt;google-app-engine&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tornado"&gt;tornado&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webapp"&gt;webapp&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webpy"&gt;webpy&lt;/a&gt;&lt;/p&gt;



</summary><category term="bret-taylor"/><category term="comet"/><category term="django"/><category term="epoll"/><category term="friendfeed"/><category term="google-app-engine"/><category term="python"/><category term="tornado"/><category term="webapp"/><category term="webpy"/></entry><entry><title>svnpubsub.py</title><link href="https://simonwillison.net/2009/Sep/6/svnpubsub/#atom-tag" rel="alternate"/><published>2009-09-06T21:50:01+00:00</published><updated>2009-09-06T21:50:01+00:00</updated><id>https://simonwillison.net/2009/Sep/6/svnpubsub/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://svn.apache.org/repos/infra/infrastructure/trunk/projects/svnpubsub/svnpubsub.py"&gt;svnpubsub.py&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
A Twisted/Python powered comet API for pushing out Subversion commits, built for Apache Foundation projects.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://blogs.apache.org/infra/entry/apache_org_downtime_report"&gt;apache.org incident report for 8/28/2009&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/subversion"&gt;subversion&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/svnpubsub"&gt;svnpubsub&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/twisted"&gt;twisted&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="python"/><category term="subversion"/><category term="svnpubsub"/><category term="twisted"/></entry><entry><title>EtherPad</title><link href="https://simonwillison.net/2009/Jul/24/etherpad/#atom-tag" rel="alternate"/><published>2009-07-24T00:35:25+00:00</published><updated>2009-07-24T00:35:25+00:00</updated><id>https://simonwillison.net/2009/Jul/24/etherpad/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://etherpad.com/"&gt;EtherPad&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Outstanding implementation of an online real-time collaborative text editor—basically SubEthaEdit in your browser. I can see myself using this a lot.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/appjet"&gt;appjet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/etherpad"&gt;etherpad&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/realtime"&gt;realtime&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/subethaedit"&gt;subethaedit&lt;/a&gt;&lt;/p&gt;



</summary><category term="appjet"/><category term="comet"/><category term="etherpad"/><category term="javascript"/><category term="realtime"/><category term="subethaedit"/></entry><entry><title>Webhooks behind the firewall with Reverse HTTP</title><link href="https://simonwillison.net/2009/Jul/22/webhooks/#atom-tag" rel="alternate"/><published>2009-07-22T13:46:20+00:00</published><updated>2009-07-22T13:46:20+00:00</updated><id>https://simonwillison.net/2009/Jul/22/webhooks/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.lshift.net/blog/2009/07/21/webhooks-behind-the-firewall-with-reverse-http"&gt;Webhooks behind the firewall with Reverse HTTP&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Hookout is a Ruby / rack adapter that lets you serve a web application from behind a firewall, by binding to a Reverse HTTP proxy running on the internet (such as the free one provided by reversehttp.net). Useful for far more than just webhooks, this means you can easily expose any Ruby web service to the outside world. An implementation of this as a general purpose proxy server would make it useful for applications written in any language.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hookout"&gt;hookout&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/reversehttp"&gt;reversehttp&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ruby"&gt;ruby&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/webhooks"&gt;webhooks&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="hookout"/><category term="reversehttp"/><category term="ruby"/><category term="webhooks"/></entry><entry><title>Reverse HTTP Demo</title><link href="https://simonwillison.net/2009/Jul/21/reversehttp/#atom-tag" rel="alternate"/><published>2009-07-21T15:54:33+00:00</published><updated>2009-07-21T15:54:33+00:00</updated><id>https://simonwillison.net/2009/Jul/21/reversehttp/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.reversehttp.net/demos/demo.html"&gt;Reverse HTTP Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
This is a bit of a brain teaser—a web server running in JavaScript in your browser which uses long polling comet to respond to incoming HTTP requests channelled through a “Reverse HTTP” proxy.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="http://www.reversehttp.net/"&gt;ReverseHttp&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/reversehttp"&gt;reversehttp&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="javascript"/><category term="reversehttp"/></entry><entry><title>Paul Buchheit: Make your site faster and cheaper to operate in one easy step</title><link href="https://simonwillison.net/2009/Apr/17/paul/#atom-tag" rel="alternate"/><published>2009-04-17T17:19:44+00:00</published><updated>2009-04-17T17:19:44+00:00</updated><id>https://simonwillison.net/2009/Apr/17/paul/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://paulbuchheit.blogspot.com/2009/04/make-your-site-faster-and-cheaper-to.html"&gt;Paul Buchheit: Make your site faster and cheaper to operate in one easy step&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Paul promotes gzip encoding using nginx as a proxy, and mentions that FriendFeed use a “custom, epoll-based python server” as their application server. Does that mean that they’re serving their real-time comet feeds directly from Python?


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/epoll"&gt;epoll&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/friendfeed"&gt;friendfeed&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gzip"&gt;gzip&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/nginx"&gt;nginx&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/paul-buchheit"&gt;paul-buchheit&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="epoll"/><category term="friendfeed"/><category term="gzip"/><category term="nginx"/><category term="paul-buchheit"/><category term="python"/></entry><entry><title>Visualising Radio, pushing, not pulling</title><link href="https://simonwillison.net/2009/Jan/13/whomwahcom/#atom-tag" rel="alternate"/><published>2009-01-13T00:59:31+00:00</published><updated>2009-01-13T00:59:31+00:00</updated><id>https://simonwillison.net/2009/Jan/13/whomwahcom/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://whomwah.com/2009/01/12/visualising-radio-pushing-not-pulling/"&gt;Visualising Radio, pushing, not pulling&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The BBC’s new radio player uses Comet over a Flash XMLsocket connection transport, with an ActiveMQ message queue behind the scenes. I’d like to know what server they’re using to broadcast out to the XMLsocket connections.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/activemq"&gt;activemq&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bbc"&gt;bbc&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/duncan-robertson"&gt;duncan-robertson&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/flash"&gt;flash&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/xmlsocket"&gt;xmlsocket&lt;/a&gt;&lt;/p&gt;



</summary><category term="activemq"/><category term="bbc"/><category term="comet"/><category term="duncan-robertson"/><category term="flash"/><category term="javascript"/><category term="xmlsocket"/></entry><entry><title>ptth (Reverse HTTP) implementation in a browser using Long Poll COMET</title><link href="https://simonwillison.net/2008/Dec/8/ptth/#atom-tag" rel="alternate"/><published>2008-12-08T17:22:42+00:00</published><updated>2008-12-08T17:22:42+00:00</updated><id>https://simonwillison.net/2008/Dec/8/ptth/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://ulaluma.com/pyx/archives/2008/12/ptth_reverse_ht.html"&gt;ptth (Reverse HTTP) implementation in a browser using Long Poll COMET&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Donovan Preston experiments with the cleverly named idea of ptth, where servers send HTTP requests to clients.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/donovanpreston"&gt;donovanpreston&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ptth"&gt;ptth&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="donovanpreston"/><category term="http"/><category term="ptth"/></entry><entry><title>FriendFeed launch a real-time API</title><link href="https://simonwillison.net/2008/Oct/22/friendfeed/#atom-tag" rel="alternate"/><published>2008-10-22T14:18:56+00:00</published><updated>2008-10-22T14:18:56+00:00</updated><id>https://simonwillison.net/2008/Oct/22/friendfeed/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://blog.friendfeed.com/2008/10/keeping-it-real-with-friendfeed-real_21.html"&gt;FriendFeed launch a real-time API&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
This is huge: JSONP plus long polling Comet, with “everything since X” tokens to ensure you don’t miss anything. This is the first open Comet API I’ve seen anywhere. Combine this with FriendFeed’s regular API (which allows arbitrary message posting) and you’ve got a really powerful tool for hackers who want to experiment with Comet without rigging up their own infrastructure.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/apis"&gt;apis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/friendfeed"&gt;friendfeed&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/json"&gt;json&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jsonp"&gt;jsonp&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/realtime"&gt;realtime&lt;/a&gt;&lt;/p&gt;



</summary><category term="apis"/><category term="comet"/><category term="friendfeed"/><category term="javascript"/><category term="json"/><category term="jsonp"/><category term="realtime"/></entry><entry><title>A Million-user Comet Application with Mochiweb, Part 1</title><link href="https://simonwillison.net/2008/Oct/16/millionuser/#atom-tag" rel="alternate"/><published>2008-10-16T14:16:18+00:00</published><updated>2008-10-16T14:16:18+00:00</updated><id>https://simonwillison.net/2008/Oct/16/millionuser/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1/"&gt;A Million-user Comet Application with Mochiweb, Part 1&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Richard Jones explores Mochiweb, Erlang and linux kernel tuning for building a high performance comet server. Does this mean real-time web features are coming to last.fm?


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/erlang"&gt;erlang&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/lastfm"&gt;lastfm&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mochiweb"&gt;mochiweb&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/realtimeweb"&gt;realtimeweb&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/richard-jones"&gt;richard-jones&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="erlang"/><category term="lastfm"/><category term="mochiweb"/><category term="realtimeweb"/><category term="richard-jones"/></entry><entry><title>Private Messages with cometD Chat</title><link href="https://simonwillison.net/2008/Oct/16/cometd/#atom-tag" rel="alternate"/><published>2008-10-16T14:14:31+00:00</published><updated>2008-10-16T14:14:31+00:00</updated><id>https://simonwillison.net/2008/Oct/16/cometd/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cometdaily.com/2008/10/14/private-messages-with-cometd-chat/"&gt;Private Messages with cometD Chat&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
cometd-java (a Java servlet reference implementation of the Bayeux protocol) can be extended with BayeuxService subclasses that run within the server itself.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/bayeux"&gt;bayeux&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cometd"&gt;cometd&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cometdjava"&gt;cometdjava&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/java"&gt;java&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;&lt;/p&gt;



</summary><category term="bayeux"/><category term="comet"/><category term="cometd"/><category term="cometdjava"/><category term="java"/><category term="javascript"/></entry><entry><title>View your FriendFeed in real-time</title><link href="https://simonwillison.net/2008/Oct/16/friendfeed/#atom-tag" rel="alternate"/><published>2008-10-16T14:06:16+00:00</published><updated>2008-10-16T14:06:16+00:00</updated><id>https://simonwillison.net/2008/Oct/16/friendfeed/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://blog.friendfeed.com/2008/10/view-your-friendfeed-in-real-time.html"&gt;View your FriendFeed in real-time&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
FriendFeed become the latest site to enable real-time updates using the long-polling variant of Comet. The real-time Web was something of a theme at this year’s FOWA, with talks on message queues, XMPP and scaling Comet at Meebo.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/fowa2008"&gt;fowa2008&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/friendfeed"&gt;friendfeed&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/meebo"&gt;meebo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/realtimeweb"&gt;realtimeweb&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/xmpp"&gt;xmpp&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="fowa2008"/><category term="friendfeed"/><category term="meebo"/><category term="realtimeweb"/><category term="xmpp"/></entry><entry><title>Spawning + Django</title><link href="https://simonwillison.net/2008/Jul/31/spawning/#atom-tag" rel="alternate"/><published>2008-07-31T10:56:21+00:00</published><updated>2008-07-31T10:56:21+00:00</updated><id>https://simonwillison.net/2008/Jul/31/spawning/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.eflorenzano.com/blog/post/spawning-django/"&gt;Spawning + Django&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The latest version of Spawning (a fast Python web server built on top of the Eventlet non-blocking coroutine networking library) can run Django applications out of the box, using threads and processes to work around the blocking nature of the ORM’s database drivers. Eric Florenzano reports better performance than Apache and mod_wsgi, and is now hosting his site on it.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/eric-florenzano"&gt;eric-florenzano&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/eventlet"&gt;eventlet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/spawning"&gt;spawning&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="django"/><category term="eric-florenzano"/><category term="eventlet"/><category term="python"/><category term="spawning"/></entry><entry><title>How Comet Brings Instant Messaging to meebo</title><link href="https://simonwillison.net/2008/Jul/27/meebo/#atom-tag" rel="alternate"/><published>2008-07-27T11:18:35+00:00</published><updated>2008-07-27T11:18:35+00:00</updated><id>https://simonwillison.net/2008/Jul/27/meebo/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://news.oreilly.com/2008/07/how-comet-brings-instant-messa.html"&gt;How Comet Brings Instant Messaging to meebo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“What started off as a hack appears to be fulfilling one of the most basic needs of the Web, which is live synchronous interaction”—Jian Shen


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/jianshen"&gt;jianshen&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/meebo"&gt;meebo&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="javascript"/><category term="jianshen"/><category term="meebo"/></entry><entry><title>Independence Day: HTML5 WebSocket Liberates Comet From Hacks</title><link href="https://simonwillison.net/2008/Jul/4/comet/#atom-tag" rel="alternate"/><published>2008-07-04T09:54:55+00:00</published><updated>2008-07-04T09:54:55+00:00</updated><id>https://simonwillison.net/2008/Jul/4/comet/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cometdaily.com/2008/07/04/html5-websocket/"&gt;Independence Day: HTML5 WebSocket Liberates Comet From Hacks&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The HTML5 spec now includes WebSocket, a TCP-style persistent socket mechanism between client and server using an HTTP handshake to work around firewalls. The Orbited comet implementation provides a WebSocket compatible API to existing browsers today, and can also act as a firewall/proxy between WebSocket and regular TCP sockets, allowing browsers to talk to things like XMPP servers using Orbited to bridge the gap.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/html5"&gt;html5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/orbited"&gt;orbited&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sockets"&gt;sockets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tcpsocket"&gt;tcpsocket&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/xmpp"&gt;xmpp&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="html5"/><category term="orbited"/><category term="sockets"/><category term="tcpsocket"/><category term="websockets"/><category term="xmpp"/></entry><entry><title>Enough Already with the Connections!</title><link href="https://simonwillison.net/2008/Jun/30/comet/#atom-tag" rel="alternate"/><published>2008-06-30T09:27:52+00:00</published><updated>2008-06-30T09:27:52+00:00</updated><id>https://simonwillison.net/2008/Jun/30/comet/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://cometdaily.com/2008/06/30/enough-already-with-the-connections/"&gt;Enough Already with the Connections!&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Comet doesn’t mean making long-lived HTTP  connections (which most browsers do anyway thanks to HTTP keep-alive), it means making long-held HTTP requests. I’m guilty of spreading this misinformation in the past.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/comet"&gt;comet&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/connections"&gt;connections&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/correction"&gt;correction&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/http"&gt;http&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/keepalive"&gt;keepalive&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/requests"&gt;requests&lt;/a&gt;&lt;/p&gt;



</summary><category term="comet"/><category term="connections"/><category term="correction"/><category term="http"/><category term="keepalive"/><category term="requests"/></entry></feed>