ActionCable is a component of the Rails framework that provides real-time communication capabilities using WebSockets—a protocol that provides two-way communication between the client and the server. This tutorial will guide you on how to use ActionCable to build a real-time application with a public chatroom example.
Before we start, make sure that:
You have the latest version of Rails installed. If not, you can install it with:
gem install rails
You have Redis installed and running in your local machine since ActionCable uses Redis as a pub/sub service for real-time features.
brew install redis
redis-server /usr/local/etc/redis.conf
Your environment can handle the WebSocket protocol.
Start by creating a new Rails application:
rails new chatroom
cd chatroom
Next, we need to configure the cable adapter to use Redis. Open up config/cable.yml and set the development configuration:
development:
adapter: redis
url: redis://localhost:6379/1
channel_prefix: chatroom_development
Channels are the means through which messages are delivered in ActionCable. They act like controllers in the MVC architecture except that they work on a many-to-one basis.
You can generate a new channel using the Rails generator:
rails generate channel Chatroom
This will generate several files including app/channels/chatroom_channel.rb. Update chatroom_channel.rb to subscribe to a stream:
class ChatroomChannel < ApplicationCable::Channel
def subscribed
stream_from "chatroom_channel"
end
def unsubscribed
# Any cleanup needed when the channel is unsubscribed
end
end
To broadcast a message to a particular stream, two steps are required:
Inside chatroom_channel.rb, let's add a speak method:
class ChatroomChannel < ApplicationCable::Channel
def speak(data)
ActionCable.server.broadcast 'chatroom_channel', message: data['message']
end
end
We will create a new JavaScript function that listens for the received event in app/assets/javascripts/channels/chatroom.js:
App.chatroom = App.cable.subscriptions.create("ChatroomChannel", {
connected: function() {},
disconnected: function() {},
received: function(data) {
alert(data['message']);
},
speak: function(message) {
return this.perform('speak', {
message: message
});
}
});
Now, we can update the view and make the channel functional.
<input id="chat-input" type="text">
<button id="send-btn">Send</button>
<script>
document.getElementById("send-btn").addEventListener('click', function() {
App.chatroom.speak(document.getElementById('chat-input').value);
});
</script>
If your ActionCable application runs into issues, try the following:
Using ActionCable can seem daunting at first, but once set up, it's a powerful tool for creating real-time features in a Rails app.