Skip to main content
WebSockets Tutorial
CHAPTER 10 Beginner

Handling Connection States and Errors

Updated: May 14, 2026
25 min read

# CHAPTER 10

Handling Connection States and Errors

1. Introduction

In the real world, internet connections are messy. Users walk into elevators, switch from Wi-Fi to cellular networks, or close their laptops. A professional WebSocket application doesn't just crash when the connection drops—it elegantly handles the error, informs the user, and automatically tries to reconnect in the background. In this chapter, we will build a robust auto-reconnection strategy to handle volatile network states.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Identify common reasons for WebSocket disconnections.
  • Implement an automatic reconnection script using setTimeout.
  • Utilize Exponential Backoff to prevent server flooding.
  • Build a user-friendly UI that accurately reflects connection states.

3. Beginner-Friendly Explanation

Imagine a dog on a leash (the connection). If the leash accidentally slips out of your hand (the connection drops), a poorly trained dog will just run away forever (the app breaks). A well-trained dog (a professional app) will immediately realize it is loose, wait a second, and walk back to you so you can grab the leash again. If you aren't there, it will wait a little longer, then look for you again. This is called Auto-Reconnection.

4. Real-World Examples

  • Slack Desktop App: If you unplug your ethernet cable, Slack shows a grey banner at the top saying "Connecting...". The moment you plug it back in, the banner turns green and disappears. The app automatically re-established the socket without requiring you to refresh the page.

5. Step-by-Step Tutorial

Let's build an auto-reconnecting WebSocket client. We will encapsulate our connection logic inside a function so we can call it repeatedly.

Step 1: Create a function called connect(). Step 2: Inside connect(), initialize the WebSocket. Step 3: Inside the onclose event, call setTimeout() to run connect() again after a short delay. Step 4: Implement Exponential Backoff to increase the delay if the server is offline.

6. The Reconnection Strategy

Here is a complete vanilla JavaScript implementation of an auto-reconnecting socket.

7. JavaScript Examples

javascript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
const serverUrl = "wss://echo.websocket.events";
let socket;
let reconnectInterval = 1000; // Start at 1 second
let maxReconnectInterval = 30000; // Max out at 30 seconds

function connect() {
    console.log("Attempting to connect...");
    socket = new WebSocket(serverUrl);

    socket.onopen = function() {
        console.log("🟢 Connected!");
        // Reset the interval upon successful connection
        reconnectInterval = 1000; 
        updateUI(true);
    };

    socket.onmessage = function(event) {
        console.log("Message:", event.data);
    };

    socket.onclose = function(event) {
        console.log("🔴 Disconnected.");
        updateUI(false);
        
        // Exponential Backoff: double the interval each time it fails
        // but don't exceed the max interval.
        reconnectInterval = Math.min(reconnectInterval * 1.5, maxReconnectInterval);
        
        console.log(`Will try to reconnect in ${reconnectInterval / 1000} seconds...`);
        
        // Try to connect again
        setTimeout(connect, reconnectInterval);
    };

    socket.onerror = function(error) {
        console.error("Socket error occurred. Close event will fire next.");
        // We do not call connect() here, because onclose will fire immediately after onerror.
    };
}

// Function to update the User Interface
function updateUI(isConnected) {
    const banner = document.getElementById('status-banner');
    if (isConnected) {
        banner.style.display = 'none';
    } else {
        banner.style.display = 'block';
        banner.innerText = "Connection lost. Reconnecting...";
    }
}

// Start the initial connection
connect();

8. What is Exponential Backoff?

If a server crashes, thousands of clients will be disconnected simultaneously. If every client tries to reconnect exactly 1 second later, they will hit the server with a massive wave of requests the moment it reboots, potentially crashing it again! Exponential Backoff solves this. The client waits 1s, then 1.5s, then 2.25s, then 3.3s, up to a maximum limit (e.g., 30s). This spreads out the load and saves the client's battery life.

9. Heartbeats (Ping/Pong)

Sometimes, a connection drops, but the browser doesn't realize it (e.g., a "zombie" connection). To detect this, clients should implement a heartbeat.
javascript
123456789101112131415
let pingInterval;

socket.onopen = function() {
    // Send a 'ping' every 30 seconds
    pingInterval = setInterval(() => {
        if(socket.readyState === WebSocket.OPEN) {
            socket.send(JSON.stringify({ type: 'ping' }));
        }
    }, 30000);
};

socket.onclose = function() {
    // Stop pinging if closed
    clearInterval(pingInterval);
};

10. Best Practices

  • Never put reconnect logic in onerror: Because onerror is immediately followed by onclose, putting connect() in both places will spawn two sockets simultaneously, creating a memory leak.
  • Max Retry Limits: Consider stopping the reconnection attempts after 5 minutes and showing the user a button that says "Click to Reconnect manually" to save CPU.

11. Common Mistakes

  • Losing References: When you create a new socket = new WebSocket(), the old socket object is gone. Ensure any external functions relying on socket check that it exists and is OPEN before trying to use it.

12. Mini Exercises

  1. 1. Implement the code from Section 7 in an HTML file.
  1. 2. Turn off your Wi-Fi.
  1. 3. Watch the console. You will see it try to reconnect, and the time between attempts will grow longer and longer.

13. Coding Challenges

Challenge 1: Modify the reconnect script so that it adds a bit of "Jitter" (a random number of milliseconds between 1 and 500) to the reconnectInterval. This ensures that even if 1,000 clients start backoff at the same time, they won't hit the server at the exact same millisecond.

14. MCQs with Answers

Question 1

What is the primary purpose of Exponential Backoff?

Question 2

Why do we clear the ping interval (clearInterval) inside the onclose event?

15. Interview Questions

  • Q: Describe how you would implement a heartbeat system to detect "zombie" WebSocket connections.
  • Q: If a WebSocket connection drops, why shouldn't the client attempt to reconnect every 100 milliseconds?

16. FAQs

Q: Does the browser automatically queue messages if I try to send while disconnected? A: No. If you call .send() while the socket is closed, it throws an error and the message is lost. You must build your own queuing system in JavaScript if you want offline support.

17. Summary

In Chapter 10, we elevated our code from a simple script to a resilient application. By wrapping our connection logic in a function and utilizing setTimeout combined with Exponential Backoff, our application can gracefully survive network interruptions, server restarts, and "zombie" connections.

18. Next Chapter Recommendation

Our application is stable, but currently, anyone can connect to it. What if we only want logged-in users to access the WebSocket? Proceed to Chapter 11: WebSocket Authentication Basics to learn how to secure your real-time data.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·