ActionCable and WebSockets - Part 1(The Basics)

One of the best thing about Rails is the ease with which it allows you to develop web apps quickly by providing some sensible conventions.

And with Rails 5, it allows you to make real-time web apps in a breeze

Introducing ActionCable.. a real time framework for communication over websockets.

But before we proceed any further, let's spend some time discussing how we got to the action cable.. or particularly, the web sockets.

When the web started becoming more dynamic with ajax and js advances, we, as developers, started finding ways to make our applications more real-time.


One of the earliest solutions that came up was Polling.

The client send requests over HTTP at regular intervals... a simple and robust solution to implement !!

The interval plays a critical role here:

In order to give any real-time experience to the client, the polling interval needs to be small enough to make the user effectively believe that app is almost live with some network latency may be.

But there were problems :

If we try to make it more real-time by reducing polling interval, our servers didn't like it mainly because of the way the polling.. or rather HTTP works.

Here's a sample implementation from IBM


HTTP is a stateless protocol. The server and client are aware of each other only during the current request. Afterward, both of them forget about each other.

Which means... ?

For each request, there is additional data in the form of headers which gets transmitted through the network and therefore, the communication was inefficient.

As per this google's whitepaper, typical headers size of 700-800 bytes is common.

Assuming 800 bytes,

For 1k clients polling every second, network throughput = 800 * 1000 = 0.763 MBps... For 10k clients... 7.63 MBps.


This was more like looping via setTimeout instead of doing it via setInterval.

The server receives the request and responds only when it has the response available.

Here's a sample implementation from IBM


But again, that was not the solution either:

It quickly falls apart once the data begin to change frequently... that would be more like regular polling itself.


Server-sent event support was added to Rails in 4.0, through ActionController::Live.
Here's a nice intro from tenderlove

A persistent unidirectional connection is made between the server and the client. The client subscribes to the server events via onmessage callbacks.

Here's a nice write-up on server sent events


That seemed promising for a while but the world stopped for IE users. As shown here, No version of IE implements EventSource interface which is required for server sent events. Whoosh! End of story.


Websockets work by maintaining a persistent bi-directional channel.

After the initial handshake, the HTTP connection is upgraded to a WebSocket connection. The data frames can then pass to and fro between client and the server until one of the sides closes it.

More info here

Here's a nice write up on websockets vs REST

web sockets

.... Coming back to action cable..

Let's get our head around some common terms that we would be using.

  • Consumer - The client of a WebSocket connection is called the consumer.
  • Channel - A channel encapsulates a logical unit of work, similar to what a controller does in a regular MVC setup.
  • Subscriber - Each consumer can, in turn, subscribe (and therefore, will become a subscriber) to multiple cable channels.

As seen in the conceptual diagrams below from here

action cable conceptual diagram

** This is just a bird-eye view. We will be covering the details as we proceed.

  • An action cable server can run as a separate server or can be mounted on the Rails App server itself.
  • The action cable server need not be a threaded server only. More info here (socket hijacking)
  • A client (Browser) interacts with rails app over HTTP / HTTPS.
  • The connection between client and ActionCable server is upgraded from HTTP to WS / WSS ( WebSocket Protocol ).
  • The Rails App enqueues the publishing in an event queue ( default implementation uses Redis for this)
  • The action cable server processes the queue.

You can follow below link to read the next part which is focussed on Implementing a sample Chat application using ActionCable.

ActionCable and WebSockets – Part 2 The Implementation

ActionCable and WebSockets - Part 2(The Implementation)

You can visit the Part 1 here.


When you create a new rails 5 application, rails generates some files for you:

new rails app

For any implementation of a websocket connection, we need both the client and the server parts of the code.


For the client side Rails provides app/assets/javascripts/cable.js which loads action_cable js and all files in channels directory.


On page load, a consumer is created and exposed via App.cable.

If we would go a little bit into the client side code for action_cable, we would find that rails does all the heavy loading like instantiating subscriptions and connections...monitoring connections etc. pretty cool.. right ?

function Consumer(url) {
            this.url = url;
            this.subscriptions = new ActionCable.Subscriptions(this);
            this.connection = new ActionCable.Connection(this);

For most practical purposes, you would not be modifying anything in this file.


Actually, rails generates an empty Connection class.
However, for almost all practical applications, we would need some sort of authorization on the incoming connections.

Here's a good tutorial on ActionCable devise authentication

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable',

      def find_verified_user
        # Assuming a successful authentication sets a signed cookie with the `user_id`
        if verified_user = User.find_by(id: cookies.signed[:user_id])
          # Raises ActionCable::Connection::Authorization::UnauthorizedError
  • Here, identified_by is a connection identifier.
    Therefore, we can use it to retrieve, and thereby disconnect, all open connections for a given user.
  • If you implement connect method, the same will be called while handling a websocket open request.
  • You can call reject_unauthorized_access if you don't want the current_user to connect

The app/channels/application_cable/channel.rb contains your ApplicationCable::Channel where you put shared logic for your channels.
It's similar to ApplicationController for controllers.

All that came right out of the box.

Let's go ahead and implement a common use case... The Chat Application.

For a chat application, we would have these three basic requirements:

  • We should be able to subscribe to a channel,
  • Publish something on that channel
  • Receive the published message on the subscribed channel.


Rails 5 provides a new channel generator which creates two new files.
One ruby file and one js file.

This generator is similar to the familiar controller generator. You specify the name of the channel (room) and one or more public methods which can be invoked as Remote Procedures ( we'll come to it in a while )


Let's see what we have in each of these files for this particular example..


# app/assets/javascripts/channels/ = App.cable.subscriptions.create "RoomChannel",
  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    # Called when there's incoming data on the websocket for this channel

  speak: ->
    @perform 'speak'
  • Rails created a subscription for the RoomChannel.

Please note that the name is exactly same as the name of the class that we have for the channel.

  • Then it provides empty implementations for three callbacks: connected, disconnected and received.
  • Then we have a speak method which basically invokes the perform method with the string speak as its argument. again, that name is important.

We'll come to it later that why this naming is important. But the good thing is rails did all that for us and we don't need to worry about it unless we override the defaults.


# app/channels/room_channel.rb
class RoomChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed

  def speak

For the channel class in ruby,

  • We have empty implementations for two callbacks, subscribed and unsubscribed.
  • Also, we have an empty implementation for our speak method.

I think you would appreciate, that we have all this structure ready and we have only typed one or two generators so far.


Here's the famous action cable demo from DHH, we'll use snippets from there to understand what each portion of code does.


# app/channels/room_channel.rb
class RoomChannel < ApplicationCable::Channel
  def subscribed
    stream_from "room_channel"

  def speak(data)
    Message.create! content: data['message']
  • The subscribed callback is called whenever a new connection is opened i.e. when you open a new tab.
    There's a corresponding unsubscribed callback as well which is invoked when a connection is closed.
  • The stream_from method is called with the name of the broadcasting pubsub queue ('room_channel' in this case). This name is important and should be same as the one on which the broadcast is invoked.
  • The speak method would be invoked as a remote procedure from the client. Here, we are just creating a new message with the passed args. You may broadcast from here itself if you want to.

However, for all practical applications, we might have a large number of subscribers and it would make sense to handle it asynchronously in a delayed job.

# app/models/message.rb
class Message < ApplicationRecord
  # That's a rails 5 equivalent of after_commit, on: :create
  after_create_commit :broadcast_self

    def broadcast_self

And here's the code for the message broadcast job.

class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(message)
    # You may render JSON or HTML itself if you want to reuse your views.
    ActionCable.server.broadcast 'room_channel', message: render_message(message)

  def render_message(message)
    # RAILS5_THING: Controller can render partial without being in scope of the controller.
                      .render(partial: 'messages/message', locals: { message: message })

Notice how we invoke the broadcast on a given named pubsub queue ( the one we passed as an argument to stream_from) with the hash that we want to broadcast.


Here's a JS equivalent of the CoffeeScript that was used in the demo.

(function() {
  // Subscribe to a channel (RoomChannel)
  // And specify event handlers for various events and any custom actions(speak). = App.cable.subscriptions.create("RoomChannel", {
    received: function(data) {
      // Do something when some data is published on the channel
    speak: function(message) {
      // We link the client-side `speak` method to `RoomChannel#speak(data)`.
      // This is possible because the server-side channel instance will automatically
      // expose the public methods declared on the class (minus the callbacks),
      // so that these can be reached as remote procedure calls
      // via a subscription's `perform` method.
      return this.perform('speak', { message: message });

  $(document).on('keypress', '[data-behavior="room_speaker"]', function(event) {
    if (event.keyCode === 13) {
      // Respond to some trigger based on which you want to
      // Invoke the speak method on the subscription created above.; = ''


I think this snippet explains why the exact string 'speak' was important.

That's because the server side ruby instance has exposed this method and this can be invoked as a Remote procedural call over the WebSocket connection.


Here's the animation showing the working of the demo app.



Initial handshake and upgrade of HTTP to WebSocket


The client subscribes to a channel


The server logs also show the initial HTTP upgrade along with the subscription to the channel.



The client invokes the channel's speak method which in turn results in a broadcast along the channel as seen in the returned frame.


The server logs show the invocation of RoomChannel#speak followed by its persistence in db and broadcast along the channel.



The websockets support cross domain requests...which means it is also vulnerable to the security threats which result due to this behavior.

Here's more info on this topic.

Rails does all the heavy lifting for you... and all you need to do is some configurations and you are good to go...

  • Action cable only allows requests from origins configured by action_cable.allowed_request_origins in your config file.
  • In case of development, this defaults to "http://localhost:3000"
  • You can configure to turn off this check using disable_request_forgery_protection in your config file.
                 .allowed_request_origins = ['', /http:\/\/ruby.*/]

# You can disable this check by :
# Rails.application.config.action_cable.disable_request_forgery_protection = true

Message queues via redis... but I don't need them in development...

Yes... the rails community also thought so.

And if you see in the config/cable.yml, you'll see the adapter is async instead of redis.

which means ?

In your development mode, the message queue is maintained in memory and will be lost once the server is shut down (which is the desired behavior in most development scenarios).

However, if you want, you may use a redis server as well by uncommenting the redis gem in the gem file and configuring config/cable.yml

  adapter: redis
  url: redis://localhost:6379/1

In production, Action Cable uses Redis by default to administer connections, channels, and sending/receiving messages over the WebSocket.

So that was a brief intro to the ActionCable which fills in the gap for real-time features in Rails.

Hope you found it interesting. Thanks for reading.



Multiple-Databases In Single Rails Application

This is a simple post to list some of the challenges faced during multiple database setup in a single rails application. The content in the post is available over the internet, we have consolidated it here to bring it at one place.

While integrating multiple third party services we felt the need to store each and every pair of request-response shared between our application and others. We decided to use database tables to store this information instead of files or other options so to have an easy disintegration of data. This helped us in filtering for some particular handshakes based on certain scenarios. Also we could pick requests that failed to respond or if any request claimed to be sent to us but never did.

We thought it would be better to place this in a separate database to avoid clouding our main database. Plus we could also avoid picking up this content while backing up our already big database, as this was not that “critical”.

So we set our sails in this direction and Rails made it very easy by letting us set up different database connections for such classes/models.
Read more

Generate paperclip missing styles on the fly

Like most developers, who use paperclip gem with their RubyOnRails applications to support picture uploading and generation of distinct styles/thumbnails of pictures, for displaying them in various views, we also do the same in a lot of our apps.

After running one such web app in production for 2 years, the app needed to be redesigned. This required us to generate couple more styles/sizes for each uploaded image.

Paperclip provides a method 'reprocess!(:style)' to generate all/one style(s).

Now, when we planned to move this new version of the app to production, we had to generate those missing styles. There were a few thousand thumbnails to be generated, and our estimated time to generate these missing styles was around half an hour. Since we could not have the site available to users without the graphics, we had to put the site in maintenance mode until the new styles got generated. We also realized that as more images get uploaded and used in the system, this downtime if we ever needed to resize graphics again would go up. We could also not do this conversion without taking the site down as more images may get uploaded while we might be resizing using a script.
Read more

'Launching Soon' – Helping Startups Build Online Identity Even before the Actual Launch

The process of brand building begins even before the actual website is launched. To have an eye-catching temporary ‘Launching Soon’ page can do a world of good for your online brand identity. It is the first step that lets you create initial buzz about your business and, therefore, it becomes imperative to have a dedicated ‘Launching Soon’ or ‘Coming Soon’ page in place. Needless to say that an aesthetic landing page embosses a long lasting and distinctive impression in the visitors’ psyche, ensuring a successful first step in climbing the long ladder.

Quick Introduction about ‘Launching Soon’

'Launching Soon' is a simple rails plugin that helps rails projects to manage a dedicated launching soon page before the actual launch date. The plugin also collects email from potential customers and can be integrated through an API to popular email marketing service providers like MailChimp & CampaignMonitor (to store customers email contacts). It lets you have a launch timer in place, and you can even have your company logo, about us section and much more. In a nutshell, all primary branding elements are present on your landing page (even before the launch of the official website). Exciting, isn’t it!

To hack over the excitement, ‘Launching Soon’ is an open source rails plugin which can be used by anyone & everyone to set up a fully customized and dedicated landing page in just a few minutes.

Why bother for a dedicated launch soon page?

Gone are the days when terrible yet oh so nostalgic ‘Under Construction’ animated GIF was appreciated by visitors. In its place, the use of more effective, functional and boiled down single ‘Coming Soon’ page is a cogent trend, capable of instantly satisfying the primary goals of the website owners.

For obvious reasons, there are other benefits of exerting efforts to have a great ‘Coming Soon’ page:

1.   Jumpstart your web presence – An effective landing page is the best way to ease the transition from going from naught to a full matured website launch.
2.    Engage with the visitors – Think from where you can benefit the most, a garish graphic which says coming soon or one page site that interacts with the visitors.
3.    Capture user data – This is perhaps one of the most important aspects of having a landing page. It lets you gather a database of genuinely interested users to whom you can send a newsletter notifying the release of your website. Big enough to help your site gain momentum.
4.    Search engine optimization – Getting a domain name booked is not enough. It is essential and imperative to have something substantial online immediately rather than wait for the final product.

With Launching Soon, it is possible to encompass all the above mentioned aspects without any rigorous development and design hassles. With a simple rails plug and play you would be up and running within minutes with your landing page, buzzing about your business and building an online identity. So, if you need a launching soon page then this is it…'Launching Soon' can be a near perfect solution.

Get the app code at:

Note - Currently ‘Launching Soon’ works  with only rails 2.x. We are working on its compatibility with rails 3.x and would keep you posted with the updates.