WebSockets & Options for Building Real-time Applications
If the application you are building requires frequent exchanges of data between the client and server, a WebSocket connection between the two is what you want. In this article, I’ll try to explain the essential concept of a WebSocket and how they make real-time updates in applications possible. I will also briefly introduce some popular open-source libraries and frameworks that make working with WebSockets easier in your code.
So, what’s a WebSocket?
In short, a WebSocket is a sole and lasting TCP connection between a client and server that allows bidirectional, full-duplex messages to be sent and received between both ends with little overhead. Wait, what? 🤔 You have probably seen this regurgitated definition before, in many places. But to understand what a WebSocket connection really is, and why it’s necessary for real-time applications, it often helps to first understand what happens during an HTTP request-response cycle…
An HTTP request-response Cycle ⏫ ⏬
When a user’s types a URL into their browser and hits send, the browser (the client) sends an HTTP request to another computer (the server), asking for data. Upon receiving the request, a TCP connection is opened between the two sides. The server then sends a response either containing the data or perhaps some kind of error if the data couldn’t be retrieved. Upon the client receiving the response, the TCP connection is closed.
This one-way message delivery of first asking for something and then receiving something in return occurs over a single TCP connection, which is terminated once that cycle completes. If the user then decides to request another resource from the server or perhaps make a post, another HTTP request-response cycle ensues and another TCP is opened and closed.
The takeaway idea is that each time the request-response cycle occurs a new connection must be made, which comes with a lot of overhead, including request and response headers. HTTP was never really made for long-lasting connections between a client and server, where real-time updates are needed.
WebSockets 🔌
A WebSocket connection is also a transfer protocol like HTTP. They are both layered over a TCP connection. A WebSocket connection however only uses a single TCP connection that remains open so that both the client and the server may freely send and receive messages as many times as needed until one side terminates the connection.
The initial request from a client to a compatible server to open a WebSocket connection is also delivered over HTTP. Upon receiving the initial request, a server will see “Upgrade” in the request header, which initiates a “handshake” between the client and server. The handshake involves some exchange of authenticating data and an agreement over what format the data will be transferred with (i.e. JSON, XML, etc). Once these subprotocols are established, the TCP connection is upgraded to a WebSocket connection and it remains open until one party leaves.
WebSockets greatly speed up delivery times of messages sent between a client and server. This difference can be most appreciated for applications that need to run in real-time. Instant messaging, gaming, or any application that depends on event-driven interaction from the user is more than likely using WebSocket connections.
Use Case 🐍 (slither.io)
Remember the snake game from the old Nokia phones? Here’s a real-life example of a browser game using a WebSocket library called Socket.IO
Okay… I want it. How do I get it?
Assuming we are coding in JavaScript, the barebones DIY approach would be to use the WebSocket object and its methods. JavaScript.info has a great tutorial worth checking out to get the idea. But if we want some of the work abstracted away under the hood and subscribe to APIs that allow us to write less code, we probably want to use a WebSocket library or framework.
Let’s explore some popular options in no particular order. Each will have it’s merits depending on what you need it for (e.g. client and/or server) or what runtime you are developing on (e.g. Node.js). The list of libraries below is biased towards Javascript and Node because they are ones widely used (or it the other way around 🤔). However, if you require a WebSocket library for another language, there is a list of libraries curated by language. I’ve also included a couple paid solutions if you need a more hands-off experience.
Open-Source WebSocket Libraries/Frameworks:
- ws (https://github.com/websockets/ws)
- Socket.io (https://socket.io/)
- Nodejs-WebSocket (https://github.com/sitegui/nodejs-websocket)
- SocketCluster (https://github.com/SocketCluster/socketcluster)
- WebSocket-Node (https://github.com/theturtle32/WebSocket-Node)
- Faye (https://www.npmjs.com/package/faye-websocket)
- SignalIR (https://dotnet.microsoft.com/apps/aspnet/signalr)
Paid/Managed Solutions:
- Pusher (https://pusher.com/websockets)
- Ably (https://ably.com/)
One of the added benefits of using a paid/managed tool is that much of the process of project set-up is facilitated for you based on simply choosing your tech stack and following instructions. In addition, at least in the case of Pusher-js, you don’t have to interact the WebSockets API at all. All of this functionality is baked into their API and happens under the hood. This means you can write less code to get up and running.
In summary, WebSockets allow a client and server to both send and receive messages/data independently from one another over the same, lasting TCP connection. WebSocket libraries can give us an easier way to set the terms of the “handshake” and manage how those connections are made and remade across your real-time application 🎮