Using websockets (ActionCable) with Rails app
Websockets are a flexible communications protocol (similar to http) that allows developers to create duplex communications in their web apps. For example, HTTP allows for delivery of data from the server to the client, but generally only when the client sends a request to the server. With websockets, and the ws:// protocol, servers can also poll for clients to send data at specific times. This allows for real time update of content, such as with chat applications or live news feeds.
ActionCable History
Enter ActionCable. ActionCable was released with Rails 5 and was a relatively late addition of websockets to the Rails tech stack. There was previously no websocket support, with only third party libraries and Javascript workarounds. Now, with your modern Rails installation, you should ActionCable ready to go with some simple tweaks.
Starting with ActionCable
- Making an ActionCable route.
First, you set up an ActionCable route by adding the following code to your ‘routes.rb’ file:
mount ActionCable.server => '/cable'
2. Make a channel for your data feed. You can use the default rails generator for this:
rails g channel messages
In the sample code I am presenting, we are creating an ActionCable implementation of a messaging app.
The above generator will generate the following channel code:
class MessagesChannel < ApplicationCable::Channeldef subscribeddef unsubscribed# Any cleanup needed when channel is unsubscribedendend
3. After creating that channel, you will now have to access it from your client. This is done by default in Rails in the consumer.js Javascript file
// app/javascript/channels/consumer.js
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
import { createConsumer } from "@rails/actioncable"
export default createConsumer()
Then, to connect to specific channels, you can utilize this code, which will subscribe your Rails app to the requested channel.
// app/javascript/channels/messages_channel.js
import consumer from "./consumer"
consumer.subscriptions.create({ channel: "MessagesChannel", room: "Best Room" })
4. The last part of utilizing ActionCable is to broadcast to the channel in question. You would normally do this in another part of the Rails app.
MessagesChannel.broadcast_to(
current_user,
title: 'New things!',
body: 'All the news fit to print'
)
Conclusion
This is a description of the basic components of using ActionCable with your Rails app. It has definitely been simplified from past implementations without Action Cable, and shows the basic core loop of the ActionCable implementation, where you have subscriptions to a channel you set up, then subscribe to the channel from the consumer, and then lastly broadcast to the channel from the Rails app to provide data to the consumers.