ELI5: Websockets (Explained in simple terms)
You may have come across the term ‘WebSockets’ and are looking for more basic information. What are websockets? How can I use them? These are some great questions, which i’ll answer below, along with:
- What’s the alternative?
- Why WebSockets?
- What are some cool implementations of WebSockets?
- How do WebSockets actually work?
- What do I need to know about WebSocket security?
Unlike a lot of ELI5’s (explain-like-i’m-five) out there, I will actually attempt to explain like you’re five:
<eli5> One day while you’re playing, you decide you want to send your model train across the room from your juice box to your teddy bear. You need to build a track do it! So you build your track across the room and run your train across. Mission accomplished! But after your train goes back to your juice-box, your dad trips over the track and you have to build again! That’s what happens without WebSockets.
Now, your dad sees your love for trains and decides to buy you a cool new electric train set. You build the track in a loop one time, plug it in, and now the train can keep going back and forth between the juice-box and Teddy all day long! Thanks for the WebSocket, dad!</eli5>
OK, that was a pretty simple analogy, so i’ll elaborate. WebSockets are a protocol that supersedes traditional HTTP (the protocol your web browser client uses everyday to request and load websites from a server). Traditionally, HTTP connections open, send data back and forth between the server and the client, and then close when finished. When a user needs more data, they send another request which leads to another connection, another response, and another connection closure.
What’s the alternative?
What if you want the connection open to facilitate real-time data without making a new connection? Before websockets, a technique called ‘long-polling’ was used. It was akin to keeping an HTTP connection open while the server was waiting for data from the client. But every time a client finished sending data, the connection was closed and re-opened. While it is a fine method for many applications, it introduces unneccesary ‘overhead’… a persistent connection solution was in demand!
Enter WebSockets. Since first introduced in a 2011 paper called The WebSocket Protocol (Fette and Melnikov), WebSockets have grown in popularity. From the paper:
The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code.”
OK, so we know that we have a two-way connection that stays open. But what is untrusted code?
Untrusted code esentially means that your server should be connected directly to the application it is meant to receive websocket connections from, but it could be connected to something pretending to be the application and trying to do something malicious. We will use this assumption to ensure that our server won’t allow the websocket connection to access our private data or otherwise hack our website. More on that in the security section below.
Why should I use Websockets?
Because of the train analogy above, we don’t need to ‘re-build’ connections every time we send data back and forth. This reduces the overhead on our server and allows for better performance through fewer connections. We don’t need to send the HTTP header back-and-forth every time data is transmitted, so the latency (ping) is reduced and we can acheive a real-time connection.
What are some cool implementations of WebSockets?
One popular library is socket.io. From the official website:
Socket.IO enables real-time, bidirectional and event-based communication.
It works on every platform, browser or device, focusing equally on reliability and speed.
It is easy to set up, and works on every platform! You can get Socket.IO installed in your package and running in a matter of minutes. Socket.IO will manage the serializing and compression of data so that you don’t have to. It will also fall back to long-polling in the event that the socket connection isn’t working. If you’re looking to learn about Socket.IO, I would reccommend the Building a Node.js WebSocket Chat App with Socket.io and React project. You set up a real-time Chat application with different rooms and users.
One cool service that uses WebSockets is called Pusher. Pusher allows easy management of WebSockets as an alternative to APIs. Want to pull stock data and update a chart in realtime? What about a service that provides real-time location data of other users? Pusher offers an easy solution that facilitates the WebSocket connection between your server and your application. They also have a ton of free tutorials on how to use the service. I would reccommend the Build A Live Map Application With React. It’s a simple application that is great for React beginners or those looking to learn about WebSockets!
How do websockets actually work?
Websockets start with an HTTP request to a websocket url (i.e. ws://example.com). The server receives this request, understands that the client is trying to set up a websocket and responds with a status code ‘101’ which means we’re switching from HTTP to something else, as well as a couple of other headers to clarify that we want to use a WebSocket connection. Let’s take a look at a connection I’ve made in the Chrome DevTools.
Looks pretty confusing, right? It’s not that bad once we break everything down. We can see the original request URL and response to upgrade from the server in the initial ‘Response Headers’ section:
Connection: Upgrade(Server agrees that we’re not using basic HTTP anymore).
Upgrade: websocket(We agree that a WebSocket will replace the HTTP connection).
Sec-Websocket-Accept: a9adskljads(This is a hash of the WebSocket ‘key’. It is in place to ensure we don’t accidentally receive data from a previous WebSocket).
Via: 1.1 vegur(This is a proxy that our server is using in this example, as the host and the origin are different below).
In the ‘Request Headers’ coming from our browser, there is quite a bit more information. These are similar to normal HTTP request headers, but I will touch on them here, with the ones related to WebSockets at the top:
Sec-WebSocket-Extensions: permessag-deflate; client_max_window_bits(Extensions to the websocket protocol — Helps facilitate the WebSocket by allowing for data compression algorithms and specifying how the data is actually sent).
Sec-WebSocket-Key: 07asdjlads...(Used to ensure the WebSocket connection isn’t accessed accidentally by another non-WebSocket HTTP connection to the same server, like a normal page load).
Sec-Websocket-Version: 13(Version of WebSocket standard that is agreed upon. Older versions are missing key features like the above headers that were added over time).
Accecpt-Encoding: gzip, deflate, br(Standard HTTP — Identifies compression methods meant to make data smaller in size and therefore faster to send).
Accept-Language: en-US(Standard HTTP header for Encoding language of the data).
Cache-Control: no-cache(Standard HTTP — Up to developers to specify how long information should be saved locally — Not related to WebSockets).
Pragma: no-cache(A backwards-compatible header used before
Cache-Controlwas a web standard).
Host: schedulerrr.herokuapp.com(Standard HTTP header for the host domain).
Origin: https://rexx.tech(Standard HTTP header for the original domain that made the request).
User-Agent: Mozilla...AppleWebKit...Chrome(Standard HTTP header — Historically meant to display different content for different browsers, but isn’t very relevent today).
What do I need to know about WebSocket security?
Security considerations for WebSockets are similar to normal HTTP communication — You should always assume that the response could be malicious and code your server in a way that no damage can be done. Two common attacks include:
- SQL Injection attacks — If your website uses WebSocket data to make SQL requests, you must ensure you escape inputs to make sure the client isn’t capable of accessing or deleting data that they shouldn’t.
- Cross-Site-Scripting, or XSS Attacks — When an attacker hi-jacks a connection in order to send code to an unsuspecting user. You can get around this by setting Session-cookies on your servers initial connection upgrade response, which will ensure that your client is talking to the server and not a savvy 12-year-old that wants your credit card information to buy Fortnite skins.
- Further to above, enable CORs on your website by verifying the
Originheader from above on your servers back-end before you send/receive sensitive data.
There a couple more security items you should know about such as rate and payload limiting to help prevent a DDOS attack, and creating a solid communication protocol to detect and deflect hackers. These are discussed further here.
WebSockets are a great way to stream information between a server and a client — Whether it is stock data, live sports scores, or a simple chat app, you can use WebSockets to provide a fully real-time experience for your users! If you are looking to go even deeper, consider this Conceptual Deep-Dive.