A look into RealTime, WebSockets, and Warp Cable

--

I started learning programming because I want to build a web platform for students to exchange writing feedback without having to wait for a teacher to give it.

Feedback needs to be CASK — consensual, actionable, specific, and kind. While the task of encouraging that philosophy online would be a feat in and of itself, it would be even more difficult were there significant delay between each piece of feedback exchanged. How likely would it be for you to change anything on your paper if you had to wait days (or even minutes, really) until someone gave you a suggestion? What if you had questions about that suggestion?

Enter the need for real-time connectivity.

I. WSS (WebSocket Secure) Connection

WebSockets allow client-server connections to remain open — bi-directionally — so that the server can send information back to the client without a request from the client.

In traditional client-server interactions made over the HTTProtocol, the client sends requests to to the server, to which the server responds; the server cannot send something to the client without having received that request.

The resulting constant pinging back and forth between the client and server creates more latency, or more time and bandwidth spent in exchanging information. Not only does it take more time for the user, it also adds to the load on the server.

Over the WSS protocol, however, that changes. The server can send data to the client whenever preset conditions are met. Think of these preset conditions as event listeners; they kick into action in response to premeditated changes.

II. HTTP to WSS: Establishing the WebSocket Connection

In order to establish a WebSocket connection, one must first rely on the HTTP protocol for the initial client-server handshake.

Once the connection is established, it remains open until further action that closes the connection.

Here’s a more-detailed breakdown of how the WSS (WebSocket Secure) connection is made.

Pretty cool.

III. A quick detour to a previous project: FlatChat

In Pablo Argueta and my previous exploration of WebSockets, we built a real-time chat application named FlatChat that uses a Rails back end and connects users over the WSS. Our data flow looked like the following:

We used a built-in Rails module called the ActionCable. ActionCable allows you to establish WebSocket connections between server and clients, and creates classes for them.

The Channel class was preset to listen for the client-action of sending a message. When that happens, the Message model created an instance of the message, and sent it to the Job model, which then rendered it and emitted the event to all clients that were subscribed to the Channel, or in this case, a chat room.

As you see, real-time isn’t exactly simultaneous — under the hood, it’s a series of chain reactions that occur really fast. I like to think of it as a Rube Goldberg machine where each part responds to the previous action.

A → B → C → D → …

So how much work do you have to put in to get this functionality?

As of September 2018, you can install the Warp Cable gem.

IV. Warp Cable lets you set up client-server interactions over both HTTP and WSS protocol — and connects the data coming in from the front end to persist it on the back end.

According to its creator Joshua Miles, “Warp Cable is a tool for rapid development of socket-based Rails applications. It’s a Ruby gem that allows the user to set up client-server interactions over both HTTP and WSS protocols — and connects the data coming in on the front end to persist on the back end.”

Warp Cable still uses ActionCable but simplifies the server-side response protocol by creating the other classes for you. It manages the communication between the classes and the WarpController by offering its own methods. In lieu of writing the code yourself to create socket connections, you can use the WarpController to both establish them over HTTP and maintain them over WSS without having to create a separate channel class.

V. A quick review of what controllers do

In general, controllers bridge model operations with data coming in over the HTTProtocol. User inputs come in through the front end and you make your app do CRUD operations on the back end based on what comes in.

VI. What the WarpController does

The Warp Controller accomplishes what controllers do — the main differences are that:

  1. each method will yield <output>, rather than render json: <output>; and that
  2. clients use subscribe and trigger methods over the WSS in lieu of initiating server requests over the HTTP (using fetch) every time.

Subscribe and trigger methods take in the following 4 arguments:

  1. Controller name
  2. Method name
  3. Params object
  4. Callback function

They effectively do the same thing, but one should use:

  • subscribe to get a resource (multiple times for a single request), e.g. index/show; and
  • trigger for actions taken against a resource, e.g. create, update, delete.

Maintaining a WebSocket connection open can be done by adding warp_resources, which is added by WarpCable and creates both WSS and HTTP access to a single controller, to the app/config/routes.rb:

Rails.application.routes.draw do
warp_resources :users
end

By making the WS connections remain open and listening to the ActiveRecord for resource updates, Warp Controller methods have the ability to respond to the client changes multiple times for a single request, then re-yielding the output when the relevant data changes.

I hope this serves as an intro to understanding WebSockets and how “real-time” exchanges work. WarpCable effectively allows the same data to be exchanged with less overhead and less latency. Hope you have fun building your apps with real-time functionalities.

--

--

:: teaching, writing, coding :: Jeannie Kim

Trips down the rabbit hole - acknowledging fully that the path to learning is rarely straight. If you feel that way, you are not alone.