Building Real-Time Web Applications with Rails and WebSockets
Introduction: In this blog post, we will explore how to create a real-time web application using Rails and WebSockets. We’ll cover the setup process, creating routes, generating controllers and channels, and integrating client-side JavaScript to establish a WebSocket connection. By the end, you’ll have a functional real-time application that broadcasts messages to connected clients.
Setting Up the Rails Application:
To begin, let’s set up a new Rails application with the necessary dependencies. Open your terminal and execute the following commands:
rails new websocket_action_cable
cd websocket_action_cable
Next, let’s generate the required components:
- Generating a Channel:
rails g channel alerts
2. Generating a Controller:
rails g controller pages home
Run the Rails Server: Start the Rails server by executing the following command in your terminal:
rails s
Defining Routes: Open the config/routes.rb
file and update it as follows:
Rails.application.routes.draw do
get 'pages/home'
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
post "/hello", to: "pages#hello"
root "pages#home"
end
Creating Page Controller:
Open the `pages_controller.rb` file located in the `app/controllers` folder and add the following code:
class PagesController < ApplicationController
def hello
ActionCable.server.broadcast 'AlertsChannel', "Hello from the Rails app."
end
end
Creating the Pages Home View:
Open the `home.html.erb` file located in the `app/views/pages` folder and add the following code:
<%= button_to "Say Hello", hello_path %>
Creating the Alerts Channel:
Open the `alerts_channel.rb` file located in the `app/channels` folder and add the following code:
class AlertsChannel < ApplicationCable::Channel
def subscribed
stream_from 'AlertsChannel'
end
end
Setting up the Vite Client:
In a separate terminal window, create a new Vite project:
npm create vite@latest
# Answer the prompts to set up the project
cd vite_project
Open two separate terminal windows, one for the Rails server and the other for the client-side application.
In the Rails terminal window, start the server:
rails s
Back in the Vite project terminal window, install the necessary dependencies:
npm install
npm run dev
Open the URL `http://localhost:5173/` in your browser.
bundle add rack-cors:
Create a new file named `cors.rb` in the `config/initializers` folder and add the following code:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
methods: %i[get post put patch delete options head]
end
end
Creating WebSocket Connection for the Client:
Locate the `main.js` file in the Vite project and clear its contents. Then, add the following code:
function createSocket() {
const socket_url = 'ws://localhost:3000/cable';
const socket = new WebSocket(socket_url);
socket.onopen = function(event) {
console.log("Connected to the Rails server.");
const msg = {
command: "subscribe",
identifier: JSON.stringify({
id: 1,
channel: 'AlertsChannel'
})
};
socket.send(JSON.stringify(msg));
};
socket.onmessage = function(event) {
const data = JSON.parse(event.data);
if (data.type === 'ping') {
return;
}
if (data.message) {
console.log(data.message);
}
console.log("Received data from server", event.data);
};
socket.onclose = function(event) {
console.log("Disconnected from the server.");
};
socket.onerror = function(error) {
console.log('WebSocket error observed:', error);
};
}
createSocket();
You can also generate a scaffold for the `Post` model:
rails g scaffold Post title body:text
rails db:create && rails db:migrate
In the `posts_controller.rb` file located in the `app/controllers` folder, add the following line after saving a post:
ActionCable.server.broadcast 'AlertsChannel', "Created a post from the Rails side with title: #{@post.title} and body: #{@post.body}"
Congratulations! You have successfully built a real-time web application using Rails Action Cable for WebSocket communication and Vite as the front-end development tool. The Rails server and the Vite-powered client can now communicate in real-time, providing a dynamic and interactive user experience. Feel free to explore further and enhance your application with additional features. Happy coding!