FullStack Labs

Please Upgrade Your Browser.

Unfortunately, Internet Explorer is an outdated browser and we do not currently support it. To have the best browsing experience, please upgrade to Microsoft Edge, Google Chrome or Safari.
Upgrade
Welcome to FullStack Labs. We use cookies to enable better features on our website. Cookies help us tailor content to your interests and locations and provide many other benefits of the site. For more information, please see our Cookies Policy and Privacy Policy.

WebSockets in Rails

Written by 
Sinduja Raghavendra
,
Software Engineer
WebSockets in Rails
blog post background
Recent Posts
Six Ways to Handle Concurrency in the JVM
Is there value in learning Vanilla JavaScript?
How to be efficient in remote design work in multicultural teams

In today's world, real-time communication has become an essential feature of many web applications. WebSockets provide a way to achieve this in a fast, reliable, and efficient manner. In this blog post, we will dive into WebSockets in Rails and how they can be used to build real-time applications.

Table of contents

What are WebSockets?

WebSockets are a protocol that provides full-duplex communication between a client and servers. Unlike traditional HTTP requests, WebSockets maintain an open connection between the client and the server, allowing real-time communication. WebSockets are useful in a variety of applications, including chat systems, online games, and real-time data displays.

Using WebSockets in Rails

Rails provide support for WebSockets through its Action Cable framework. Action Cable enables developers to add real-time functionality to their applications easily. To use WebSockets in Rails, you need to set up a channel, which is a communication channel that allows the client and server to send and receive data.

Here's how you can set up a WebSocket channel in Rails:

Create a new channel

You can create a new channel in Rails using the following command:


rails generate channel <channel_name>

This will generate a new channel in the app/channels directory.

Implement the channel

Next, you need to implement the channel by defining the actions that can be performed on it. For example, let's say you have a chat channel that allows users to send and receive messages.


class ChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "chat_#{params[:room]}"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    ActionCable.server.broadcast "chat_#{params[:room]}", message: data['message']
  end
end

In this example, the subscribed method is called when the client subscribes to the channel. It uses the stream_from method to start streaming data from the channel. The unsubscribed method is called when the client unsubscribes from the channel. The speak method is called when the client sends data to the channel.

Handling lost connections: WebSockets are built on top of the TCP protocol, which provides reliability and fault tolerance. However, in case of a lost connection, the server will not be notified until it tries to send data and fails. To handle lost connections, you can implement a heartbeat mechanism where the client periodically sends a message to the server to indicate that it is still connected. If the server does not receive a heartbeat within a certain timeframe, it can assume that the connection has been lost and take appropriate action (e.g., stop sending messages or remove the client from the channel).

Sending data from the client to the server: When the client sends data to the server via a WebSocket connection, it can be sent as a string, JSON, or any other format that can be serialized. In Rails, you can use the speak method (or any other name you choose) to handle incoming data from the client. The data can be accessed via the data parameter of the method, which contains the payload sent by the client.

Ruby handling of session alive: By default, Rails uses a cookie-based session stored to maintain the session state for each client. The session data is stored on the server and identified by a session ID that is stored in a cookie on the client's browser. When a client connects to a WebSocket channel, the session ID can be passed as a parameter in the WebSocket URL. The server can then use this ID to retrieve the session data and keep the session alive. However, it's important to note that WebSocket connections are stateful, which means that the server maintains a connection with the client for the duration of the session. This can put a strain on server resources if there are many clients connected at the same time.

Create a view

Finally, you need to create a view that displays the data sent over the WebSocket. The example given below uses Vanilla JavaScript. However, using a framework such as React or Vue.js is recommended to create a view that displays the data sent over the WebSocket.


App.chat = App.cable.subscriptions.create("ChatChannel", {
  connected: function() {
    // Called when the subscription is ready for use on the server
  },

  disconnected: function() {
    // Called when the subscription has been terminated by the server
  },

  received: function(data) {
    // Called when there's incoming data on the websocket for this channel
  }
});

In this example, the connected method is called when the subscription is ready to use on the server. The disconnected method is called when the server has terminated the subscription. The received method is called when there is incoming data on the WebSocket for this channel.

You can use the received method to tie the data received over the WebSocket to an input or other element in your view. You can use the received method. This method is called when there is incoming data on the WebSocket for this channel.

For example, let's say you have an input field with the id #chat-input and a div with the id #chat-messages in your view. You can update the #chat-messages div content with the data received over the WebSocket, like presented below:


App.chat = App.cable.subscriptions.create("ChatChannel", {
  connected: function() {
    // Called when the subscription is ready for use on the server
   },

   disconnected: function() {
      // Called when the subscription has been terminated by the  server
   },

   received: function(data) {
     // Called when there's incoming data on the websocket for this channel
   $("#chat-messages").append("<p>" + data.message + "</p>");
   }
});

In the example above, we're using jQuery to select the #chat-messages div and append a new paragraph element with the received data. This code can be modified to update any element on the web page with the data received over the WebSocket.

Therefore, WebSockets provide a powerful way to add real-time functionality to your web applications. And Rails, through its ActionCable framework, makes it much easier to add WebSockets.

Sinduja Raghavendra
Written by
Sinduja Raghavendra
Sinduja Raghavendra

Sinduja is a Software Engineer at FullStack Labs. Based in Sacramento, she has three years of experience working in industry-leading companies like Dell and Hewlett & Packard. Sinduja is also a Ph.D candidate in Wireless Sensor Networks at Visvesvaraya Technological University.

People having a meeting on a glass room.
Join Our Team
We are looking for developers committed to writing the best code and deploying flawless apps in a small team setting.
view careers
Desktop screens shown as slices from a top angle.
Case Studies
It's not only about results, it's also about how we helped our clients get there and achieve their goals.
view case studies
Phone with an app screen on it.
Our Playbook
Our step-by-step process for designing, developing, and maintaining exceptional custom software solutions.
VIEW OUR playbook
FullStack Labs Icon

Let's Talk!

We’d love to learn more about your project.
Engagements start at $75,000.

company name
name
email
phone
Type of project
How did you hear about us?
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.