August 2018

Monthly Archives

Know Your Options: Alternatives for Live Data in Rails

Or: Alternatives to web sockets/action cable (in case, you know, you’re a masochist)


For the uninitiated, web sockets allow for a continuous connection with data- our gmail account’s fancy ability to fancily deliver emails in fancy real time is one example of this, as would be a stock ticker that updates in real time (real time meaning milliseconds). Action cable is rail’s fancy new way of integrating web sockets, and while everyone is terribly excited about action cable’s potential and web socket’s capabilities I figured I’d give a little bit of back ground as to why web sockets are considered to be so neat.


Back before web sockets, there were three popular ways to open a continuous data connection-
1 Polling- Polling involves the client asking the server, on a set interval (say, three seconds) if there is any new data.Returning to the “live comments” example, let’s say we have a page with a comments section. To create this application with polling, we can write some Javascript to ask the server every three seconds for the latest comment data in JSON format. If there is new data, we can update the comment section.
The advantage of polling is that it’s rock-solid and extremely simple to set up. For these reasons, it’s in wide use all over the Web. It’s also very resistant to network outage and latency – if you miss 1 or 2 polls because the network went out, for example, no problem! You just keep polling until eventually it works again. Also, thanks to the stateless nature of HTTP, IP address changes (say, a mobile client with data roaming) won’t break the application.

However, regarding scalability… You’re adding considerable load to your servers by causing everyclient to hit your server every 3 seconds. There are ways to alleviate this – HTTP caching is a very good one – but the fact remains, your server will have to return a response to every client every 3 seconds, no matter what.
Also, while polling is acceptable for “live” applications (most people won’t notice a 3-second delay in your chat app or comments thread), it isn’t appropriate for rapid back-and-forth (like games) or streaming data.
2 Long-Polling – Long-polling is a bit like polling, but without a set interval between requests (or “polls”). The client sends a request to the server for new data – if the server has new data, then it sends a response back like normal. If there isn’t any new data, though, it holds the request open, effectively creating a persistent connection, and then when it receives new data, completes the response.


Exactly how this is accomplished varies. There are several “sub-techniques” of long-polling you may have heard of, likeBOSH and Comet. Suffice it so say, long-polling techniques are considerably more complicated than polling, and can often involve weird hacks like hidden iframes.


Long-polling is great when data doesn’t change very often. Let’s say we connect to our live comments, and 45 seconds later a new comment is added. Instead of 15 polls to the server over 45 seconds from a single client, a server would open only 1 persistent connection.


However, it quickly falls apart if data changes often. Instead of a live comments section, consider a stock ticker. A stock’s price can changes at the millisecond interval (or faster!) during a trading day. That means any time the client asks for new data, the server will return a response immediately. This can get out of hand quickly, because as soon as the client gets back a response it will make a new request. This could result in 5-10 requests per second per client. You would be wise to implement some limits in your client! Then again, as soon as you’ve done that, your application isn’t really RealTime™ anymore!


3 Server-sent Events are essentially a one-way connection from the server to the client. Clients can’t use SSEs to send data back to the server. Server-sent Events got turned into a browser API back in 2006, and is currently supported by every major browserexcept any version of Internet Explorer.


Using server-side events is really quite simple from the (Javascript) client’s side. You set up an EventSourceobject, define an onmessage callback describing what you’ll do when you get a new message from the server, and you’re off to the races.

Server-sent event support was added to Rails in 4.0, throughActionController::Live.
Serving a client with SSEs requires a persistent connection. This means a few things: using Server-sent events won’t work pretty much at all on Heroku, since they’ll terminate any connections after 30 seconds. Unicorn will do the same thing, and WEBrick won’t work at all. So you’re stuck using Puma or Thin, and you can’t be on Heroku. Oh, and no one using your site can use Internet Explorer. You can see why ActionController::Live hasn’t caught on. It’s too bad – the API is really simple and for most implementations (“live” comments, for example) SSE’s would work great.


(All descriptions from THIS fantastic article written by Nate Berkopec:


So, how does this effect us? Well, I think it’s only a matter of time before all of us, in our new development jobs or in our awesome, shinny side projects, will want to at least take a shot at creating a real-time updating, persistent data connection enacting, super fantastic application, and when the time comes to create it, it’ll be nice to have a head start in knowing what your options are.