Thursday, October 17, 2013

An overview of pub/sub in the Ruby on Rails ecosystem

It’s not AJAX, it’s PUB/SUB

The following will look at the basics of pub-sub and review a number of pub-sub solutions for ruby/rails apps.

For many web apps, we want to notify our users about activity within their network. This is broken down into two steps 1) knowing when there’s a notification and 2) displaying it.

With AJAX, we can send asynchronous requests to check app endpoints for updates, but this means lots of requests.

It’s 2013 and the new way to address this challenge is called pub-sub. There’s a publisher (publishing notifications) and our users, once online, become subscribers to the publications.

The means the messages are pushed instead of pulled.

The transfer of these pushed notifications commonly utilize either Websockets or the Server Sent Event (SSE) methods to push data to the clients.

The websocket protocol is established over http or https, using an upgrade handshake request from the client to the server. If properly validated, a full-duplex data transfer is initialized between the client and server on the ws or wss protocol. As of Thursday October 17, 2013 all the latest browsers except Android browser support the latest specification (RFC 6455) of the WebSocket protocol.

Server Side Events are part of the HTML5 EventSource API. The browser is set up listen for text/event_stream server responses. They are not currently supported for IE.

It's important to understand what Websockets and SSE are so you can make the right decision for which technology you want to integrate into your production stack, and to understand the limitations of each.

What tools are available to do pub-sub in your rails app? Here are a few options...

Pusher is a commercial service that handles all websocket interaction and exposes an API for publishing to subscribers.


-Should work out of the box making it fast to integrate, and offer the same basic features we'd get from Faye
-Rails 3 compatible


-Seems like the android browser is out of the picture since it's websockets backed.
-Connections limited based on your service plan
-Not Free


Rails 4 offers the ActionController::Live mixin to do SSE.

-No additional gems needed

-No IE support

For Rails 3 Aleksey Magusev shows a dead simple implementation which seems to work in Rails 3. A simple response object sent to establish and feed the SSE stream, and it's handled by an instance of the EventSource class in the HTML5 compliant browsers. In a load-balanced server environment, this solution might not be enough since connections could be left open.


Faye, has been around for a while (2009) and recently hit v1.0. It is an implementation of the Bayeux protocol over websockets (supported by faye-websocket) and uses an in-memory or redis engine for storage and message semantics. Enabling redis supports load-balanced (distributed) servers. It utilizes it's own websocket impmentation faye-websocket - and a redis client - faye-redis -

-Actively maintained, mature project
-Can push messages for Chats and more
-Can be used across multiple devices
-Solid candidate for a production pub-sub platform

-Comprehensive configuration options might be overkill
-Requires configuring redis

Closing Thoughts

True pub/sub means turning on websockets or SSE. The faye platform offers a complete solution for production systems, with fine tune-able configurations for single direction and bi-directional streams. If you are looking to extensively use pub/sub in your app, it’s worth taking the time to intrgrate faye. For quick streams, the rails solution offers less strings attached approach.


  1. I like the Faye project. I investigated this awhile back with a simple proof of concept. Open up four different kinds of browsers: Firefox, Chrome, Safari, and (gasp) Internet explorer.

    I published a message. Out of all the solutions I tried (Socket.IO, websockets, and Faye), Faye was the only one that worked right out of the box without any nonsense.

  2. Rock and roll. Thank you for sharing that testing tip.