Websockets With Rails::ActionCable

Websockets are the next level protocol in connecting your users to live updating content. This is a brief overview of websockets with ActionCable.

What are websockets?

Simply speaking it is a protocol to allow a device to send and receive messages to another device over a single TCP connection.

This allows a browser to keep a websocket connection open to a server and send or receive messages without the overhead of re-negociating a new connection every time. Perfect for applications with small, two-way, messages being sent. Such as a chat app, a multi-player game, or a document editor with mutli-user support.

Why Websockets?

Simply stated: Websockets keep the connection open, allowing a unique, identifiable, low overhead communication mechanism for messages.

Nate Berkopec has an excellent blog post going into more detail, and the tradeoffs here.

Why Rails::ActionCable?

Good question. There are a number of more established websocket frameworks out there, such as Socket.io. It is possible to implement a rails app living in harmony with websockets in another stack. However, Rails has officially merged ActionCable. Which means your websocket code lives inside your app abiding by Rails' simplicity and REST-like conventions. ActionCable's goal is to make using websockets simple.

ActionCable Overview

Before you can accomplish anything there are a few server dependencies.

  1. Multi-threaded. You can mount it as an engine if you're already running on a multi-threaded server, but for development I used a version of the example script to launch a standalone server1.
  2. Redis, ActionCable uses it, so you must have it. Alternatives are not yet available at time of writing2.

Once the basic dependencies are met there are a few concepts and new objects to understand.

At it's most basic level a consumer opens a websocket connection to the server, subscribes to (or is assigned) a specific channel, and sends or receives messages on that channel. All via a unique, maintained, identifiable, connection between the client and server.

ActionCable provides three base classes to handle each step:

  1. Connection

    A Connection object is instantiated for ever websocket connection created. The Connection becomes the parent of all subscribed channels and is responsible for authentication and authorization of the... erm... connection. Worth mentioning as you'll likely need to monkeypatch this in real world applications.

  2. Channel

    A Channel can be thought of a bi-directional controller (except persistent in memory and RPC, not garbage collected post-request and RESTful :/). A consumer subscribes to one or many channels after connecting, then sends or receives messages over those channels. The server can send a message to an individual or all subscribed consumers. You'll have to define a channel in order to subscribe to it.

  3. ActionCable (JavaScript)

    The ActionCable JavaScript library is used to create a connection on the client, subscribe to channels, send messages, and handle received messages. Be sure to include it in your JavaScript assets manifest file.

That's it! ActionCable does an amazing job abstracting websockets into a simple and usable framework. Time permitting I will have a tutorial and more detailed example of it's use, until then checkout the actioncable examples.

There continues to be a debate on if ActionCable fits into the rails ecosystem. I'm not completely sold that it does. However, as far as usability and simplicity to pick up is concerned, ActionCable fits nicely into Rails. Time will tell if it is received well by the community.