Deep Dive Into WebSockets
WebSockets are part of a huge number of modern applications. They became the preferred choice for many developers seeking to build an interactive and modern user experience.
WebSockets Architecture
In a traditional client-server architecture, when the client wants to talk with the server, it makes an HTTP request to the server and the server responds back. This architecture means that in order to allow real-time communications, the client should be sending a request to the server every second or so… Obviously, we do not want that.
This is where WebSockets can help. WebSockets allow to send messages between the server and the browser, without closing the connection between them. The server is able to push fresh data to the client when it receives it.
How Do WebSockets Work?
WebSocket is based on one TCP connection. It operates on the same ports as HTTP (80 and 443). This connection is opened through an Upgrade request sent via HTTP.
The idea is simple:
1. The client sends an HTTP request with the Upgrade header;
2. The server responds with a status code 101, telling the client to switch protocol;
3. The WebSocket connection is established.
The request from the client will look like this:
GET / HTTP/1.1
Host: example.com
Upgrade: WebSockets
Connection: Upgrade
And the response from the server will look like this:
HTTP/1.1 101 Switching Protocol
Upgrade: WebSockets
Connection: Upgrade
The Upgrade header is used to indicate a change of protocol. It could be from HTTP/1.1 to HTTP/2.0 or to WebSockets… The client can indicate a preference, but the final decision will be made by the server. This is heavily detailed in RFC 2616 and RFC 6455.
WebSocket Connection
WebSocket is not HTTP. The handshake is made through HTTP, but once the connection is opened, the WebSocket uses raw TCP to read/write data.
The WebSocket protocol has been designed to be compatible with the existing HTTP infrastructure. This is why the handshake is made in the HTTP territory.
Messages sent are small and only have 6 bytes of overhead (2 for the header, and 4 for the mask value). It is perfectly suited for low-latency applications.
Main Problems
One of the most recurrent problems when using WebSockets is the broken connection. This will happen when the client or the server does not respond. Your code should gracefully handle a way to close and refresh the connection frequently, to make sure that the communication stays smooth.
Also, WebSockets require higher availability than HTTP servers due to persistent connections. Therefore, scaling WebSockets is non-trivial and will involve some trade-offs. The server should be able to scale when needed. This is not as easy as it seems, because most connections stays idle. You will have to track connections.
Browser Compatibility
Today, most browsers support WebSockets. The major libraries will also support a fallback to HTTP if the browser is not compatible.
What about the data?
Once the connection is established, bot client and server can send data to each other in real-time.
Data Transfer Patterns
The most common pattern is to use the WebSocket to notify the client that a notification, or an update, is available. The client will then fetch the data through HTTP. In this case, the WebSocket connection is only used to send notifications to the client.
In some cases, you might need to send data in real-time. This will happen when you work with a multiplayer game, a chat application, or an IoT application, for example. There are no limitations, as long as you need real-time communications, you might need a WebSocket.
Security
When it comes to security, WebSockets can be fairly secure when implemented correctly. For example, a WebSocket connection can be encrypted with SSL/TLS. This would show as wss://. You can also apply the same security policies as HTTP connections, like CORS restrictions. Also, when it comes to authentication, you are free to implement it as you wish (cookie headers, JWT…).
Real Life Applications
You can find applications of WebSockets in a lot of modern applications… For example, real-time notifications is one common use case.
You could also imagine a multiplayer game, chat applications, real-time updates on your social feeds, collaboration tools…
As long as you need real-time bilateral communications, you can use WebSockets. It is widely used and there are many libraries to implement it without difficulties.