

How we built Pusher-JS 2.0 – part 2 – implementation - knes
http://blog.pusher.com/how-we-built-pusher-js-2-0-part-2-implementation/

======
bradgessler
This is a great write-up! We learned a lot of these lessons at Poll Everywhere
for <http://firehose.io/>, which is basically an open source version of
Pusher. We do things a few things differently though:

* We only have two transport layers: http and ws. We don't bother with a Flash polyfill.

* We start the connection via HTTP long polling and upgrade to WS if its (a) present in the client and (b) the network supports it. We've seen a lot of firewalls kill WS connections, so long polling always works.

* We treat our "push" channels more like a push edge cache. Because of flakey connections you want to hang on to the past 50-100 messages published to a channel so that flakey clients can get messages if their connection drops.

Source code is up at <https://github.com/polleverywhere/firehose> and you can
install it as a gem and have it running in 2 seconds.

I'm happy to answer questions on here if anybody's got them about building a
realtime transport layer like Pusher & Firehose!

~~~
leggetter
We've kept the FlashSocket option in there, as it ultimately means the user
gets the benefit of a WebSocket connection without native WebSocket support; a
single bidirectional connection resulting in the lowest latency possible.

Our HTTP fallback offers XHR Streaming, XHR Long-polling, IFRAME options
(streaming, polling htmlfile etc.) and JSONP-polling for older browsers.

The preference is of course a WebSocket connection, then streaming (as it
means a persistent connection is created), then long-polling, then standard
polling. The problem with any sort of polling is that it's generally
inefficient and there are periods of time where a connection isn't established
- this means data on the client may not be the most up to date (stale).

We all know: WebSocket FTW! :)

