Challenge 2: Queue Messages While Disconnected — Possible Solution ==================================================================== class ReconnectingSocket { constructor(url) { this.url = url; this.attempt = 0; this.queue = []; // messages waiting to be sent once (re)connected this.connect(); } connect() { this.socket = new WebSocket(this.url); this.socket.addEventListener("open", () => { this.attempt = 0; this._flushQueue(); // send anything that queued up while disconnected }); this.socket.addEventListener("close", () => { const delay = Math.min(1000 * 2 ** this.attempt, 30000); const jitter = Math.random() * 0.3 * delay; this.attempt++; setTimeout(() => this.connect(), delay + jitter); }); } send(data) { const message = JSON.stringify(data); if (this.socket.readyState === WebSocket.OPEN) { this.socket.send(message); } else { this.queue.push(message); // not connected right now — hold onto it } } _flushQueue() { while (this.queue.length > 0) { const message = this.queue.shift(); this.socket.send(message); } } } WHY THIS WORKS -------------- - send(data) is the ONLY method the rest of the application calls to send a message — it hides the connection-state check behind a single entry point, so calling code never needs to know or care whether the socket happens to be open right now. - The readyState === WebSocket.OPEN check (from Chapter 3) is what decides between the two paths: send immediately if the connection is live, or push onto this.queue if it isn't — this is the exact same defensive check used for the server-side broadcast pattern earlier in the course, applied here on the client instead. - _flushQueue() runs specifically inside the "open" event handler — this guarantees queued messages are sent the MOMENT a fresh connection becomes available, not on some separate timer that might fire before the new socket is actually ready. - Using .shift() (rather than iterating without removing) means each queued message is sent exactly once and then removed — if flushQueue were somehow triggered twice, there'd be nothing left in the queue to accidentally resend. - One deliberate simplification worth noting: this version has no queue size limit or expiry. A production version would likely cap the queue (dropping oldest messages, or warning the user) so a very long disconnection doesn't let the queue grow unbounded — this chapter's focus is the core send-while-disconnected mechanism, not that additional safety limit.