Let’s build a real-time Chat application with Action Cable

Chanmann Lim
lchanmann
Published in
5 min readMay 30, 2018

Building a real-time Chat application that integrated into your Rails stack is no longer novel due to the inclusion of Action Cable gem into the Rails core and there should be no excuse to start making one your own 🙌 .

Action Cable uses WebSocket connection under the hood to make bi-directional communication between the Client and Server possible. It provides both the server-side infrastructure for message queuing and broadcasting and the client-side JavaScript binding helpers to assist rapid application development.

In this article, we are going to create a simple real-time Chat application which allows users to send and stream messages from a public chat room.

User authentication and management is beyond the scope of our discussion and I leave it as a homework for you to explore on your own.

In this application, each unique user, aka. browser session, is associated with a username sequentially assigned (i.e. User1, User2, …) when the server see it for the first time.

We also configure testing facilities and follow test-driven development (TDD) approach for building the application. Finally, we’ll deploy the application to Heroku.

Fill up your coffee ☕️ and let’s hit the road!

Photo by Joshua Hibbert on Unsplash

Creating a new Rails 5 application

Please make sure that you have a compatible version of ruby, PostgreSQL and Redis installed on local development machine before moving on.

Open a terminal and run the following command (without $ sign):

$ rails new chatapp --database=postgresql

Then cd into chatapp, open Gemfile for editing and un-comment out redis gem:

Configuring for TDD-ing

As we are doing TDD, we’ll need extra testing libraries and utilities to support test-code-refactor cycle. We use rspecinstead of Rails default testing framework. We’ll also need guard-rspec, capybara, selenium-webdriver and action-cable-testing gems to do end-to-end system tests and action cable tests.

Don’t forget to bundle install!

Run guard init rspec to generate Guardfile and rails g rspec:install to generate spec/spec_helper.rb and spec/rails_helper.rb files.

Add capybara and action-cable-testing dependencies in rails_helper.rb as follow:

The TDD workspace setup is now ready! Run guard in another terminal window which observes file changes and invoke the rspec tests accordingly.

Let’s add our first test.

In guard terminal you’ll see test failing, something like:

Let’s fix the test by creating app/controllers/home_controller.rb and adding route for root url pointing to home#index.

Now the test in the guard terminal should pass.

Implementing Action Cable

Action Cable provides abstraction for WebSocket connection in the form of ActionCable::Connection, one connection instance per WebSocket connection. The Action Cable Connection class is already created in app/channels/application_cable/connection.rb for you.

On the server-side, we still need to create a channel which encapsulates the functionalities to allow for steaming of data content(e.g. chat messages) which will be consumed by the clients and for sending message to the chat room. We’ll simplify send_message to just re-broadcast the message to all connected clients.

For client to receive the data pushed from the server, it must subscribe to the right channel. On receiving data, client would then update the page content to show the new arriving message and clear message input.

To generate Chat channel with a send_message method run following command:

$ rails g channel Chat send_message
create app/channels/chat_channel.rb
identical app/assets/javascripts/cable.js
create app/assets/javascripts/channels/chat.js

Note: Only the line starts with ($) sign is the command to run in terminal, the italic text following that line is just output produced by running the command.

Adding tests for Action Cable Connection

Action Cable Connection class is the place where you authorize the incoming connection, and proceed to establish it, if all is well.

We shall test weather the connection can be established or not based on a cookie holding current username.

Adding tests for ChatChannel

We test subscribed callback for content streaming and send_message for re-broadcasting message to the channel.

Try implementing Action Cable Connection and Chat Channel on your own before seeing mine at here and here. Use Action Cable README to assist your making.

Controller logic and view

We use Redis as user counter and assign numbered username to cookies in controller and render the username along with message list and input controls in view.

Initializing Redis client

Controller tests

Now, it’s your turn to implement HomeController and make the tests pass. 👊!

Interacting with Action Cable server

The final stage for implementing a working chat application is to code the view and hook it up with Action Cable server.

Below is the end-to-end system tests for the application.

Your tasks is to create home index view and the client code to subscribe to the Chat channel and tie user sending message action to the send_message method on the server-side. Again use Action Cable README to help guide your course.

My repo for the application is hosted here, in case you need to compare with yours.

Deploying to Heroku

If you haven’t had an account with Heroku, go to https://www.heroku.com/ sign up and install Heroku Toolbelt.

Heroku comes with Free Dyno plan which we’ll use for this deployment. More details on pricing can be found on Heroku pricing page.

Login to Heroku

$ heroku login

Create a Heroku app

$ heroku create

Use Redis To Do addon

$ heroku addons:create redistogo

Replace ENV.fetch("REDIS_URL") in config/initializers/redis.rb and config/cable.yml with ENV.fetch("REDISTOGO_URL").

Deploy your code

$ git push heroku master
Counting objects: 154, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (134/134), done.
...remote:
remote: Verifying deploy... done.
To
https://git.heroku.com/thawing-springs-91931.git
* [new branch] master -> master

Visit the app in browsers

After successfully deploy your code to Heroku, you can visit your chat app by running

$ heroku open

It would look something like:

Copy the URL, open it with another browser or in a Incognito window and try it out!

It works, hooray 🎉🎉🎉!

Conclusion

We have just built and deployed a fully-tested real-time chat application with Action Cable. It seems daunting at first but Action Cable APIs is quite compact, straight forwards and well-documented which flattens out the learning curve required to get up to speed.

Although it introduces a set of new concepts and terminology to enable real-time features development in a Rails application but the power and possibilities it brings out-weight the investment one might put into understanding Action Cable.

I hope you enjoy learning about Action Cable as much as I do. Please 👏👏👏 and share if you find this useful.

--

--

Chanmann Lim
lchanmann

M.S. in Computer Science, University of Missouri-Columbia.