When WebSockets were first announced in 2011, they had some teething problems.
- Some browsers didn’t yet support WebSockets and, if they did, they had bugs and cross-browser compatibility quirks that caused unexpected behavior.
- Firewalls would sometimes block WebSockets because they didn’t recognize this (at the time) brand new protocol and its unique handshake protocol that upgrades a HTTP connection to a full-fledged bidirectional WebSocket connection.
- Proxies would sometimes determine the connection idle and close it prematurely (if the proxy understood WebSockets at all).
As a result of these teething problems, only the most daring and experimental developers would rely solely on WebSockets for realtime communication. For most of us, it became a necessity to implement a fallback protocol in case the WebSocket connection can’t be established.
WebSocket fallbacks
Even though WebSockets are unique in their full-duplex bidirectional nature, in most situations, you can achieve the same realtime behavior with a HTTP-based method, even though it’s going to be much less efficient and much more work to implement.
This is partially why libraries like Socket.IO in the JavaScript universe world and SignalR in the .NET space became so prevalent.
Both libraries start with a HTTP-based method like long polling or response streaming before attempting to establish a WebSocket connection and seamlessly shift the protocol from HTTP to WebSocket for improved latency and scalability (due to WebSockets being more resource efficient).
At Ably, we employ the same strategy for our JavaScript realtime SDK because, if the SDK loaded over HTTP, well, there’s no reason to assume HTTP won’t work without a hitch!
But is this all really necessary anymore?
According to CanIUse, WebSockets have technically been supported by all browsers since 2014. Even if there were cross-browser quirks or missing features in the years that followed, WebSockets are so prevalent nowadays (they have been for a while), it’s reasonable to assume the web API is in a good place.
In a similar vein, all the mainstream firewalls and proxies have long since been updated to understand the WebSockets protocol by now. WebSocket support on the server is in a good place as well… Right?
The state of WebSocket server support
Even when a server technology matures, it usually takes many more years for servers to adopt the updated software. Just look at HTTP where server support matured around 2017 but, at the time of this writing, is only supported on 36% of servers.
While numbers like this aren’t available for WebSockets, it is reasonable to assume that some proxies and firewalls out there still don't support WebSockets.
If you’re spinning up a new web server or otherwise control every component the WebSocket connection might traverse, this is unlikely to be a problem. You can upgrade the software, tweak the configuration. You probably don’t need a HTTP fallback.
However, many systems, especially those deployed in places like government institutions, schools, hospitals, call centers, or other enterprises might not be the most amenable to a Websocket connection by default.
Perhaps they’re running server software locked to an older version number for security and compliance reasons - basically, the server-side equivalent of going to the doctor and wrangling with Windows XP to print your prescription.
In some cases, these enterprise systems might only need a small configuration change or a quick update, but when you don’t control the stack, this isn’t usually possible.
- It might not be possible to connect with someone knowledgeable about these things at all.
- If you do, they probably won’t want to make the change hastily without first understanding the full impact on their operations and security, and that is fair enough.
- And, besides, if you are deploying software on a company’s system or device, you want it to be as easy as possible for them to say “yes” and adopt your software! If you need your customer to make changes to their system, such as updating software or configuring firewalls, this might slow down or even halt adoption of your product.
Other reasons WebSocket connections can fail in 2024
While WebSockets are generally very robust these days, connections can still fail in weird and wonderful ways that might be out of your control:
- The user’s computer might have a really strict or really outdated antivirus with a firewall component that blocks WebSocket connections.
- Perhaps their router implements an esoteric TCP timeout that affects the WebSocket underlying TCP connection.
- Maybe they’re on cellular but the mobile network provider is having trouble with WebSocket connections.
- A heuristic firewall (on the server or client) could produce a false positive.
If these sound unlikely, consider for a second GitHub issues like “cannot open WebSocket when using mobile data” posted in 2021, or this thread by a Mattermost customer (self-hosted Slack alternative) about “constant WebSocket errors” from 2022.
Instead of putting the onus on your user (or your customer’s users in the case of a company like MatterMost), you might still consider a fallback to HTTP to ensure the best possible user experience, even in the face of edge cases like these.
What’s the conclusion? Do you still need a WebSocket fallback?
WebSockets are much more prevalent than they used to be, and support in 2024 is generally excellent for new projects where you control the stack and your user is an ordinary type of consumer - for example, they open and use your app directly.
Still, connections can (and will) fail for a myriad of unpredictable reasons and usually ones out of your control.
Instead of trying to address every eventuality one at a time, a HTTP alternative effectively casts a wide net to catch and circumvent any particular problems and ensure a seamless experience for your users.
There’s no doubt a fallback is nice to have and will afford you peace of mind.
The question then becomes - is the cost of implementing this worth the upside?
Scaling WebSocket alternatives
While libraries like Socket.IO and SignalR provide HTTP fallbacks out of the box, as open source libraries, they aren’t responsible for deploying, hosting, or scaling your realtime infrastructure. That’s a problem left up to you, and it’s not a trivial one to solve.
The stateful nature of WebSockets and HTTP response streaming make them uniquely challenging to scale reliably compared to ordinary HTTP requests which are stateless and short-lived.
If you rely on a fallback, you’re not only responsible for scaling WebSockets with low latency and high uptime, but a HTTP-based alternative method as well.
Since scaling WebSockets and a HTTP-based method require a totally different approach, it could double the complexity of your implementation and the upside might not justify it for your particular needs.
The great news for developers building realtime features with Ably is that all this happens behind the scenes, allowing you to benefit from the maximum possible compatibility and efficiency without having to worry about the backend infrastructure.
If you’d like to learn more about Ably and how we deal with network issues, read more here.