Recently, Dylan talked about the long-polling technique. This method has become fairly well-disseminated, but there are some misconceptions as to the trade-offs between long-polling and streaming transports. Hopefully I can clear a couple of them up.
One of the big criticisms of long-polling is that it introduces additional latency and bandwidth costs. While these are valid concerns, they are not as pressing as they may seem. Bandwidth isn’t that big of a deal. We’re talking a few hundred bytes of overhead per event. If there are 100 events a
second minute then that’s maybe 0.5k/second overhead. Even 33.6kbps modems can handle that overhead, besides the fact that 100 events is an extreme example. As for latency, the most commonly cited cause of latency for this transport is the TCP setup/tear-down cost for each connection. But HTTP/1.1 codified the concept of Connection: Keep-alive, which allows multiple HTTP requests to be sent over the same TCP connection, so we end up with a transport very similar to streaming transports.
But there is another actual latency issue. That is, the latency of each long-polling event includes the round trip time between the browser and the server. On the other hand, the latency in streaming is equivalent to the latency of a one-way trip from the server to the browser. This has to do with how the HTTP protocol works. There are only two real states, 1) The server is waiting for a request (and cannot send data) or 2) The browser is waiting for a response (and cannot send data.) Given the confines of this protocol, a full request response cycle is necessary for any data exchange. Streaming transports step slightly outside the bounds of the protocol to achieve a latency of roughly half that of long-polling.
The benefits of long-polling though are twofold:
- First, the browser and server interact in a standards compliant manner. That’s not to say that HTTP streaming doesn’t work in standards compliant browsers, just that the strict definition of HTTP only has room for a long-polling style implementation of Comet. Some firewalls are keyed not just to particular ports but also certain protocols, particularly HTTP. If the interaction doesn’t seem to be HTTP, then these firewalls just may block the connection. Using long-polling will ensure that firewalls do not block any requests.
- The second benefit is that network resilience is built in. HTTP servers hide the details of Keep-alive versus HTTP/1.0 style interaction from the app. This means the application doesn’t care and doesn’t even know whether or not a TCP connection is interrupted, so long as requests keep coming (from a re-opened connection.) Therefore, the most basic implementation of long-polling will survive brief network outages. Recently I was using a long-polling based IRC client as well as a traditional desktop IRC client. I had a brief (about 5 seconds) network outage and my desktop IRC client lost its connection and I had to reconnect, re-authenticate, and join all my channels again. On the other hand, my web-based client was perfectly fine. That’s because the Comet server maintained the actual TCP connection to the IRC server, and it didn’t mind that my browser was disconnected for a few seconds.