WebSocket: Simultaneous Bi-Directional Client-Server Communication

Gabbie Piraino
6 min readMar 5, 2019

--

If you’ve ever tried to implement simultaneous functionality in your applications, you might have realized that the very nature of the Request-Response cycle prevents this possibility. While it’s sometimes possible to mimic instantaneous communication, wouldn’t it be better if it was actually possible? Cue WebSocket: resolving the issue of bi-directional messaging between the client(s) and server.

History of WebSocket

Before we dive into WebSocket’s functionality and implementation, I find it useful to understand where the need for WebSocket arose.

The internet originated as a collection of HTML (HyperText Markup Language) documents that linked to one another — a world wide web, if you will. As the internet developed, it eventually transitioned from static web pages to include more diverse types of information, including things like images, videos, sound files, etc. All of this information was accessible through the HTTP request-response cycle. A client would make a request — typing a website address into the search bar — the request would be sent to a server (and potentially routed a few times along the way), the server would identify the information from its database to send back to the client , and the server would respond with the identified information as an HTML document that the client’s browser would read and display within the browser.

Programming on the Web: O’Reilly

Javascript eventually introduced Dynamic HyperText Markup Language (DHTML) in order to make more dynamic web pages available. As the internet continued to develop, various techniques arose to resolve the need for full page reloads (including HTTP Polling, LiveConnect, forever frame technique). Eventually AJAX (Asynchronous JavaScript and XML) arose to rerender information to the browser (more correctly, the DOM, or Document Object Model) without requiring clients to refresh in order to display new information after interactivity. However, AJAX, and thereafter XHR Long-Polling and XHR Streaming, still doesn’t allow for bi-directional communication between a server and a client. Prior to WebSocket, all information was uni-directional and constrained to the request-response cycle.

What is WebSocket?

WebSocket is a relatively new piece of the web development toolkit. In short, it’s a new type of communications protocol that is different from HTTP. WebSocket allows a single TCP socket connection to be hijacked so that the client-server relationship can relay bi-directional, full-duplex (or sometimes also referred to as double-duplex) messages instantaneously. An example of a full-duplex communications system include your cell phone: both parties can speak and hear the other at the same time.

Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable: SOPHIE DEBENEDETTO

More explicitly, WebSocket is designed to run on HTTP ports 80 and 443, and supports HTTP proxies and intermediaries. By doing so, WebSocket is compatible with HTTP protocol. In order to achieve this compatibility, the WebSocket handshake uses the HTTP Upgrade header to switch from the HTTP protocol to the WebSocket Protocol.

Most browsers support WebSocket protocol, including Chrome, Firefox, Opera, Edge, Internet Explorer, and Safari. Further, there are library implementations for the WebSocket API in Objective-C, .NET, Ruby, Java, node.js, ActionScript, and other languages.

Benefits of Using WebSocket

Though many apps might not require bi-directional messaging from the client to the server, there are many benefits to implementing WebSocket in your apps.

  1. Speed: Because of WebSocket design (inherently small payloads, persistent connection that doesn’t rely on the response-request overhead), messages can be sent and received in real-time. Further, memory use is configurable.
  2. Stability: WebSocket has been tested heavily across multiple platforms and continually passes Python’s industry-standard stress test: Autobahn Testsuite.
  3. Simplicity: WebSocket itself takes care of managing the connections, so developers can focus on functionality and what they’re actually passing in messages between the client and the server.
When to use a HTTP call instead of a WebSocket: Windows Apps Team

When considering implementing WebSocket to your application, your should first ask yourself what it will be used for — is HTTP sufficient (and will your application actually reimplement the typical request-response cycle within WebSocket)? Will a client be continually passing messages to and from the server — will the connection only be open for a short time or only send a few messages? Will the client initiate the WebSocket handshake multiple times? Will the client require multiple WebSocket connections simultaneously? If the answer to any or all of these is yes, then perhaps your app isn’t the best use-case for WebSocket.

Different Implementations of WebSocket

The various languages and frameworks have each implemented WebSocket in their own way.

Rails

In Rails, they’ve built Action Cable to work in conjunction with Redis. Action Cable can either be run on a stand-alone server or run its own processes on the application server. Every time you spin up an application, an instance of Action Cable is also created, and Rails uses Rack to open and maintain a connection: “using a channel mounted on a sub-URI of your main application to stream from certain areas of your application and broadcast to other areas” (Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable).

A tutorial for implementing Action Cable into your apps is available here.

Node.js

In Node.js, the implementation of each server environment (Go, .NET, Java, or otherwise) will be slightly different based on the HTTP server libraries that are available. Employing WebSocket requires you to use the WebSocket class (this is already built into modern browsers by default). On the server, you first need to upgrade the handshake upgrade from HTTP to WebSocket, then read the data and translate it according to the WebSocket framing protocol specification. Lastly, the server must construct the messages it’ll send to the client according to these same protocols.

A tutorial for implementing WebSocket in Node.js is available here.

Python

In Python, there are multiple libraries available to mimic the behaviors described above for Node.js. One that I found is Tornado: an asynchronous network library that can naturally handle tens of thousands of concurrent open connections. By implementing Tornado into your Python application, you can further employ WebSocket connections on a single node. The benefit here is that your connections are stateful and real-time data transfers between the client and the server are possible in ways that wouldn’t without WebSocket.

A tutorial for implementing WebSocket with Tornado is available here.

Conclusion

Overall, WebSocket is a new web protocol that can allow real-time communication between the server and client simultaneously. It’s certainly superseded other previous stopgaps to mimic the bi-directional, full-duplex functionality of WebSocket, but hasn’t overtaken all solutions (AJAX, for example), as others still have their uses when WebSocket isn’t entirely necessary. Hopefully with the above direction, you can understand the basics of WebSocket and use the resources provided to begin implementing WebSocket in your own projects.

Good luck, and happy bi-directional coding!

Resources

Wikipedia: WebSocket

Wikipedia: Comparison of WebSocket implementations

Pusher: What are WebSockets?

Microsoft: When to use a HTTP call instead of a WebSocket (or HTTP 2.0)

Real-Time Rails: Implementing WebSockets in Rails 5 with Action Cable

Hackernoon: Implementing a WebSocket server with Node.js

MDN Web Docs: Writing WebSocket client applications

Toptal: How to Create a Simple Python WebSocket Server Using Tornado

--

--

Gabbie Piraino

Current Tech Geek | Previous Book Nerd | Always Doggo Lifestyle