1"use strict";(self.webpackChunkjavascript_bit=self.webpackChunkjavascript_bit||[]).push([[4741],{259:function(n,s,a){a.d(s,{Zo:function(){return r},ah:function(){return u}});var t=a(9142);function e(n,s,a){return(s=(0,t.Z)(s))in n?Object.defineProperty(n,s,{value:a,enumerable:!0,configurable:!0,writable:!0}):n[s]=a,n}var p=a(7294);function o(n,s){var a=Object.keys(n);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(n);s&&(t=t.filter((function(s){return Object.getOwnPropertyDescriptor(n,s).enumerable}))),a.push.apply(a,t)}return a}function c(n){for(var s=1;s<arguments.length;s++){var a=null!=arguments[s]?arguments[s]:{};s%2?o(Object(a),!0).forEach((function(s){e(n,s,a[s])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(a)):o(Object(a)).forEach((function(s){Object.defineProperty(n,s,Object.getOwnPropertyDescriptor(a,s))}))}return n}var l=p.createContext({});function u(n){var s=p.useContext(l);return p.useMemo((function(){return"function"==typeof n?n(s):c(c({},s),n)}),[s,n])}var i={};function r(n){var s,a=n.components,t=n.children;return s=n.disableParentContext?"function"==typeof a?a({}):a||i:u(a),p.createElement(l.Provider,{value:s},t)}},7836:function(n,s,a){a.r(s),a.d(s,{Head:function(){return d},default:function(){return m}});var t=a(259),e=a(7294);function p(n){var s=Object.assign({p:"p",h2:"h2",ol:"ol",li:"li",span:"span",ul:"ul",a:"a",strong:"strong",table:"table",thead:"thead",tr:"tr",th:"th",tbody:"tbody",td:"td"},(0,t.ah)(),n.components);return e.createElement(e.Fragment,null,e.createElement(s.p,null,"You've built a chat app, a live dashboard, or a multiplayer game â and HTTP requests feel wrong. You're polling every 5 seconds, burning through bandwidth, and the data is always a little stale. That's the problem WebSockets solve."),"\n",e.createElement(s.p,null,"I've used WebSockets in production for real-time trading dashboards, collaborative editors, and notification systems. Here's everything I wish I knew from the start."),"\n",e.createElement(s.h2,null,"How WebSockets Work"),"\n",e.createElement(s.p,null,"WebSockets upgrade a standard HTTP connection into a persistent, full-duplex TCP connection. The flow looks like this:"),"\n",e.createElement(s.ol,null,"\n",e.createElement(s.li,null,"Client sends an HTTP ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">GET</code>'}})," request with an ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Upgrade: websocket</code>'}})," header"),"\n",e.createElement(s.li,null,"Server responds with ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">101 Switching Protocols</code>'}})),"\n",e.createElement(s.li,null,"The TCP connection stays open â both sides can send frames at any time"),"\n",e.createElement(s.li,null,"No more HTTP overhead (no headers on every message)"),"\n"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">Client â Server: GET /chat HTTP/1.1\n Upgrade: websocket\n Connection: Upgrade\n Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\n\nServer â Client: HTTP/1.1 101 Switching Protocols\n Upgrade: websocket\n Connection: Upgrade\n Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=</code></pre></div>'}}),"\n",e.createElement(s.p,null,"After the handshake, it's not HTTP anymore. It's a raw TCP socket with a lightweight framing protocol. Messages flow in both directions with minimal overhead â about 2-10 bytes of framing per message compared to hundreds of bytes of HTTP headers."),"\n",e.createElement(s.h2,null,"The Browser WebSocket API"),"\n",e.createElement(s.p,null,"The native browser API is straightforward:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> socket <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebSocket</span><span class="token punctuation">(</span><span class="token string">\'wss://example.com/chat\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\nsocket<span class="token punctuation">.</span><span class="token function-variable function">onopen</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">\'Connected\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">\'join\'</span><span class="token punctuation">,</span> <span class="token literal-property property">
1room</span><span class="token operator">:</span> <span class="token string">\'general\'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\n\nsocket<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">const</span> data <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">\'Received:\'</span><span class="token punctuation">,</span> data<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\n\nsocket<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">error</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">\'WebSocket error:\'</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\n\nsocket<span class="token punctuation">.</span><span class="token function-variable function">onclose</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Closed: code=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>event<span class="token punctuation">.</span>code<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> reason=</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>event<span class="token punctuation">.</span>reason<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token comment">// event.code tells you WHY it closed</span>\n <span class="token comment">// 1000 = normal, 1001 = going away, 1006 = abnormal (no close frame)</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,"Key things to know:"),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">wss://</code>'}})," is the secure version (always use this in production)"),"\n",e.createElement(s.li,null,e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">socket.send()</code>'}})," accepts strings, ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ArrayBuffer</code>'}}),", or ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Blob</code>'}})),"\n",e.createElement(s.li,null,e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">socket.readyState</code>'}})," gives you the current state (0=CONNECTING, 1=OPEN, 2=CLOSING, 3=CLOSED)"),"\n",e.createElement(s.li,null,"The ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">onclose</code>'}})," event's ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">code</code>'}})," field is critical for debugging â ",e.createElement(s.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close_event"},"see the full list of close codes")),"\n"),"\n",e.createElement(s.h2,null,"Using the ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ws</code>'}})," Library (Node.js)"),"\n",e.createElement(s.p,null,"On the server side, the ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ws</code>'}})," package is the standard choice. It's fast, well-maintained, and handles the HTTP upgrade for you."),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">
1import</span> <span class="token punctuation">{</span> WebSocketServer <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">\'ws\'</span><span class="token punctuation">;</span>\n\n<span class="token keyword">const</span> wss <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebSocketServer</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">port</span><span class="token operator">:</span> <span class="token number">8080</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\nwss<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'connection\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">ws<span class="token punctuation">,</span> request</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">New client from </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>request<span class="token punctuation">.</span>socket<span class="token punctuation">.</span>remoteAddress<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n ws<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'message\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token comment">// data is a Buffer by default</span>\n <span class="token keyword">const</span> message <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">\'Received:\'</span><span class="token punctuation">,</span> message<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token comment">// Echo back or broadcast</span>\n ws<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">echo</span><span class="token operator">:</span> message <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n ws<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'close\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">code<span class="token punctuation">,</span> reason</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">
1Client left: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>code<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n ws<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'error\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">err</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span><span class="token string">\'Client error:\'</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,"For broadcasting to all connected clients:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">broadcast</span><span class="token punctuation">(</span><span class="token parameter">wss<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">const</span> payload <span class="token operator">=</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>\n wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">client</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span>client<span class="token punctuation">.</span>readyState <span class="token operator">===</span> WebSocket<span class="token punctuation">.</span><span class="token constant">OPEN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n client<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>payload<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",e.createElement(s.h2,null,"Connection Lifecycle"),"\n",e.createElement(s.p,null,"Understanding the lifecycle prevents most bugs I see in production:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">CONNECTING (0) â OPEN (1) â CLOSING (2) â CLOSED (3)</code></pre></div>'}}),"\n",e.createElement(s.p,null,e.createElement(s.strong,null,"Common mistakes:")),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,"Calling ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">send()</code>'}})," before ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">onopen</code>'}})," fires â message silently drops"),"\n",e.createElement(s.li,null,"Not handling ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">onclose</code>'}})," â your app thinks it's still connected"),"\n",e.createElement(s.li,null,"Ignoring ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">readyState</code>'}})," â always check before sending"),"\n"),"\n",e.createElement(s.p,null,"A robust send function:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">function</span> <span class="token function">safeSend</span><span class="token punctuation">(</span><span class="token parameter">socket<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span>socket<span class="token punctuation">.</span>
1readyState <span class="token operator">===</span> WebSocket<span class="token punctuation">.</span><span class="token constant">OPEN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> data <span class="token operator">===</span> <span class="token string">\'string\'</span> <span class="token operator">?</span> data <span class="token operator">:</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">\'Socket not open, state:\'</span><span class="token punctuation">,</span> socket<span class="token punctuation">.</span>readyState<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",e.createElement(s.h2,null,"Reconnection Strategies"),"\n",e.createElement(s.p,null,"Connections drop. Network switches, server restarts, mobile signal loss â you need reconnection logic. Here's a production-grade approach with exponential backoff:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">ReconnectingWebSocket</span> <span class="token punctuation">{</span>\n <span class="token function">constructor</span><span class="token punctuation">(</span><span class="token parameter">url<span class="token punctuation">,</span> options <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>url <span class="token operator">=</span> url<span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>maxRetries <span class="token operator">=</span> options<span class="token punctuation">.</span>maxRetries <span class="token operator">??</span> <span class="token number">Infinity</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>maxDelay <span class="token operator">=</span> options<span class="token punctuation">.</span>maxDelay <span class="token operator">??</span> <span class="token number">30000</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>baseDelay <span class="token operator">=</span> options<span class="token punctuation">.</span>baseDelay <span class="token operator">??</span> <span class="token number">1000</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>retries <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>manualClose <span class="token operator">=</span> <span class="token boolean">
1false</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>handlers <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>\n\n <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">connect</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebSocket</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token punctuation">.</span><span class="token function-variable function">onopen</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>retries <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">\'open\'</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">;</span>\n\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">\'message\'</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token punctuation">.</span><span class="token function-variable function">onclose</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">this</span><span class="token punctuation">.</span>manualClose<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">reconnect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">\'close\'</span><span class="token punctuation">,</span>
1 e<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">;</span>\n\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">emit</span><span class="token punctuation">(</span><span class="token string">\'error\'</span><span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">reconnect</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>retries <span class="token operator">>=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>maxRetries<span class="token punctuation">)</span> <span class="token keyword">return</span><span class="token punctuation">;</span>\n\n <span class="token keyword">const</span> delay <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">min</span><span class="token punctuation">(</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>baseDelay <span class="token operator">*</span> Math<span class="token punctuation">.</span><span class="token function">pow</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">.</span>retries<span class="token punctuation">)</span> <span class="token operator">+</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">,</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>maxDelay\n <span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>retries<span class="token operator">++</span><span class="token punctuation">;</span>\n\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Reconnecting in </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>Math<span class="token punctuation">.</span><span class="token function">round</span><span class="token punctuation">(</span>delay<span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">ms (attempt </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span><span class="token keyword">this</span><span class="token punctuation">.</span>retries<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">)</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> delay<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">send</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token operator">?.</span>
1readyState <span class="token operator">===</span> WebSocket<span class="token punctuation">.</span><span class="token constant">OPEN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> data <span class="token operator">===</span> <span class="token string">\'string\'</span> <span class="token operator">?</span> data <span class="token operator">:</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>manualClose <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>socket<span class="token operator">?.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">on</span><span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> handler</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>handlers<span class="token punctuation">[</span>event<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">.</span>handlers<span class="token punctuation">[</span>event<span class="token punctuation">]</span> <span class="token operator">||</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>handlers<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>handler<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n <span class="token function">emit</span><span class="token punctuation">(</span><span class="token parameter">event<span class="token punctuation">,</span> data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">this</span><span class="token punctuation">.</span>handlers<span class="token punctuation">[</span>event<span class="token punctuation">]</span><span class="token operator">?.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">h</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">h</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,"The jitter (",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Math.random() * 1000</code>'}}),') prevents the "thundering herd" problem â if 1000 clients all disconnect at once, they won\'t all reconnect simultaneously.'),"\n",e.createElement(s.h2,null,"Heartbeat / Ping-Pong"),"\n",e.createElement(s.p,null,"Silent disconnections are a real problem. A connection can look open but the TCP link is dead (think: laptop suspended). The solution is heartbeats."),"\n",e.createElement(s.p,null,"The WebSocket protocol has built-in ping/pong frames, but the browser API doesn't expose them. For browsers, implement application-level heartbeats:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// Client-side heartbeat</span>\n<span class="token keyword">let</span> heartbeatInterval<span class="token punctuation">;</span>\n<span class="token keyword">let</span> missedPings <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> <span class="token constant">MAX_MISSED</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>\n\n<span class="token keyword">function</span> <span class="token function">startHeartbeat</span><span class="token punctuation">(</span><span class="token parameter">socket</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n missedPings <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>\n heartbeatInterval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span>socket<span class="token punctuation">.</span>
1readyState <span class="token operator">===</span> WebSocket<span class="token punctuation">.</span><span class="token constant">OPEN</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">\'ping\'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n missedPings<span class="token operator">++</span><span class="token punctuation">;</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span>missedPings <span class="token operator">></span> <span class="token constant">MAX_MISSED</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">warn</span><span class="token punctuation">(</span><span class="token string">\'Too many missed heartbeats, closing\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n socket<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span>\n <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">30000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// every 30 seconds</span>\n<span class="token punctuation">}</span>\n\n<span class="token keyword">function</span> <span class="token function">handleMessage</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span>data<span class="token punctuation">.</span>type <span class="token operator">===</span> <span class="token string">\'pong\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n missedPings <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment">// server is alive</span>\n <span class="token keyword">return</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n <span class="token comment">// handle normal messages</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,"On the server with ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ws</code>'}}),", you can use the built-in ping/pong:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> wss <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WebSocketServer</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n <span class="token literal-property property">port</span><span class="token operator">:</span> <span class="token number">8080</span><span class="token punctuation">,</span>\n <span class="token literal-property property">clientTracking</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Server-side ping every 30s</span>\n<span class="token keyword">const</span> interval <span class="token operator">=</span> <span class="token function">setInterval</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n wss<span class="token punctuation">.</span>clients<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">ws</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>ws<span class="token punctuation">.</span>isAlive<span class="token punctuation">)</span> <span class="token keyword">return</span> ws<span class="token punctuation">.</span><span class="token function">terminate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n ws<span class="token punctuation">.</span>isAlive <span class="token operator">=</span> <span class="token boolean">
1false</span><span class="token punctuation">;</span>\n ws<span class="token punctuation">.</span><span class="token function">ping</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">30000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\nwss<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'connection\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">ws</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n ws<span class="token punctuation">.</span>isAlive <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>\n ws<span class="token punctuation">.</span><span class="token function">on</span><span class="token punctuation">(</span><span class="token string">\'pong\'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> ws<span class="token punctuation">.</span>isAlive <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",e.createElement(s.h2,null,"Binary Data"),"\n",e.createElement(s.p,null,"WebSockets handle binary frames natively. This is useful for file transfers, streaming audio, or game state:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// Sending binary data</span>\n<span class="token keyword">const</span> buffer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Uint8Array</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\nsocket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Receiving â set binaryType first</span>\nsocket<span class="token punctuation">.</span>binaryType <span class="token operator">=</span> <span class="token string">\'arraybuffer\'</span><span class="token punctuation">;</span> <span class="token comment">// or \'blob\'</span>\n\nsocket<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> event<span class="token punctuation">.</span>data <span class="token operator">===</span> <span class="token string">\'string\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token comment">// text frame</span>\n <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>\n <span class="token comment">// binary frame â event.data is an ArrayBuffer</span>\n <span class="token keyword">const</span> view <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataView</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">\'First byte:\'</span><span class="token punctuation">,</span> view<span class="token punctuation">.</span><span class="token function">getUint8</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,"For file uploads over WebSocket, chunk the data:"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">sendFile</span><span class="token punctuation">(</span><span class="token parameter">socket<span class="token punctuation">,</span>
1 file</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">const</span> <span class="token constant">CHUNK_SIZE</span> <span class="token operator">=</span> <span class="token number">64</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">;</span> <span class="token comment">// 64KB chunks</span>\n <span class="token keyword">const</span> totalChunks <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">ceil</span><span class="token punctuation">(</span>file<span class="token punctuation">.</span>size <span class="token operator">/</span> <span class="token constant">CHUNK_SIZE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator"><</span> totalChunks<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n <span class="token keyword">const</span> chunk <span class="token operator">=</span> file<span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span>i <span class="token operator">*</span> <span class="token constant">CHUNK_SIZE</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token constant">CHUNK_SIZE</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token keyword">const</span> buffer <span class="token operator">=</span> <span class="token keyword">await</span> chunk<span class="token punctuation">.</span><span class="token function">arrayBuffer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span>buffer<span class="token punctuation">)</span><span class="token punctuation">;</span>\n <span class="token punctuation">}</span>\n\n socket<span class="token punctuation">.</span><span class="token function">send</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">\'file-complete\'</span><span class="token punctuation">,</span> <span class="token literal-property property">name</span><span class="token operator">:</span> file<span class="token punctuation">.</span>name <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",e.createElement(s.h2,null,"WebSocket vs SSE vs HTTP Polling"),"\n",e.createElement(s.p,null,"This is the most common architectural question. Here's when to use each:"),"\n",e.createElement(s.table,null,e.createElement(s.thead,null,e.createElement(s.tr,null,e.createElement(s.th),e.createElement(s.th,null,e.createElement(s.strong,null,"WebSockets")),e.createElement(s.th,null,e.createElement(s.strong,null,"SSE")),e.createElement(s.th,null,e.createElement(s.strong,null,"HTTP Polling")))),e.createElement(s.tbody,null,e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Direction")),e.createElement(s.td,null,"Full-duplex"),e.createElement(s.td,null,"Server â Client only"),e.createElement(s.td,null,"Client pulls")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Protocol")),e.createElement(s.td,null,e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ws://</code>'}})," / ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">wss://</code>'}})),e.createElement(s.td,null,"HTTP"),e.createElement(s.td,null,"HTTP")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Best for")),e.createElement(s.td,null,"Chat, games, collab"),e.createElement(s.td,null,"Notifications, feeds"),e.createElement(s.td,null,"Rarely the right choice")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Reconnection")),e.createElement(s.td,null,"You build it"),e.createElement(s.td,null,"Built-in"),e.createElement(s.td,null,"N/A (stateless)")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Binary")),e.createElement(s.td,null,"â
Native"),e.createElement(s.td,null,"â Text only"),e.createElement(s.td,null,"â
Via HTTP")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Proxy/Firewall")),e.createElement(s.td,null,"Sometimes blocked"),e.createElement(s.td,null,"HTTP (safe)"),e.createElement(s.td,null,"HTTP (safe)")),e.createElement(s.tr,null,e.createElement(s.td,null,e.createElement(s.strong,null,"Complexity")),e.createElement(s.td,null,"Medium-High"),e.createElement(s.td,null,"Low"),e.createElement(s.td,null,"Lowest")))
1),"\n",e.createElement(s.p,null,e.createElement(s.strong,null,"Use WebSockets when:")),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,"You need real-time bidirectional communication (chat, multiplayer, live trading)"),"\n",e.createElement(s.li,null,"Message frequency is high (many messages per second)"),"\n",e.createElement(s.li,null,"Low latency matters"),"\n"),"\n",e.createElement(s.p,null,e.createElement(s.strong,null,"Use SSE when:")),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,"Data flows server â client only (notifications, live scores, activity feeds)"),"\n",e.createElement(s.li,null,"You want simplicity â SSE is just a long-lived HTTP response"),"\n",e.createElement(s.li,null,"You need automatic reconnection for free"),"\n"),"\n",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// SSE is this simple</span>\n<span class="token keyword">const</span> source <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">EventSource</span><span class="token punctuation">(</span><span class="token string">\'/api/notifications\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\nsource<span class="token punctuation">.</span><span class="token function-variable function">onmessage</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">event</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span>event<span class="token punctuation">.</span>data<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\nsource<span class="token punctuation">.</span><span class="token function-variable function">onerror</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">\'Reconnecting...\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",e.createElement(s.p,null,e.createElement(s.strong,null,"Use HTTP polling when:")),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,"Nothing else works (restr
1ictive corporate proxies)"),"\n",e.createElement(s.li,null,"Updates are infrequent (every 30+ seconds)"),"\n",e.createElement(s.li,null,"You need it working in 5 minutes and don't care about efficiency"),"\n"),"\n",e.createElement(s.h2,null,"Key Takeaways"),"\n",e.createElement(s.ul,null,"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"WebSockets upgrade HTTP to a persistent TCP connection")," â full-duplex, low overhead after handshake"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"Always use ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">wss://</code>'}}))," in production â unencrypted WebSocket traffic is trivially intercepted"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"Build reconnection with exponential backoff and jitter")," â connections will drop, plan for it"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"Implement heartbeats")," â detect dead connections before they cause bugs"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"Use SSE for server â client only")," â it's simpler and handles reconnection for you"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"Check ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">readyState</code>'}})," before sending")," â sending to a closed socket silently fails"),"\n",e.createElement(s.li,null,e.createElement(s.strong,null,"The ",e.createElement(s.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">ws</code>'}})," library is the standard for Node.js servers")," â use it, don't roll your own parser"),"\n"),"\n",e.createElement(s.p,null,"The WebSocket API is simple. Building a reliable real-time system on top of it is not. Handle reconnection, heartbeats, and connection state properly, and you'll save yourself from the most common production incidents I've seen."))}var o=function(n){void 0===n&&(n={});var s=Object.assign({},(0,t.ah)(),n.components).wrapper;return s?e.createElement(s,n,e.createElement(p,n)):p(n)},c=a(3688),l=a(2198),u=a(9357),i=a(4992),r=a(6376),k=function(n){var s,a=n.data,t=a.previous,p=a.next,o=a.site,u=a.mdx,k=n.location,d=n.pageContext,m=n.children,g=(null===(s=o.siteMetadata)||void 0===s?void 0:s.title)||"Title",y=(d||{}).seriesPosts,f=u.fields;return e.createElement(l.Z,{location:k,title:g},e.createElement("article",{className:"blog-post",itemScope:!0,itemType:"http://schema.org/Article"},e.createElement("header",null,e.createElement("h1",{itemProp:"headline"},u.frontmatter.title),e.createElement("p",null,u.frontmatter.category&&e.createElement("span",{className:"category-pill"},u.frontmatter.category),u.frontmatter.date,(null==f?void 0:f.wordCount)>0&&e.createElement("span",{style:{marginLeft:"0.75rem",color:"inherit",opacity:.6}},"· ",Math.max(1,Math.round(f.wordCount/200))," min read"))),u.frontmatter.series&&y&&y.length>0&&e.createElement(r.Z,{seriesSlug:u.frontmatter.series,currentSlug:u.fields.slug,seriesPosts:y}),e.createElement("section",{itemProp:"articleBody"},m),e.createElement(i.Z),e.createElement("hr"),e.createElement("footer")),e.createElement("nav",{className:"blog-post-nav"},e.createElement("ul",{style:{display:"flex",flexWrap:"wrap",justifyContent:"space-between",listStyle:"none",padding:0}},e.createElement("li",null,t&&e.createElement(c.Link,{to:t.fields.slug,rel:"prev"},"â ",t.frontmatter.title)),e.createElement("li",null,p&&e.createElement(c.Link,{to:p.fields.slug,rel:"next"},p.frontmatter.title," â")))))},d=function(n){var s=n.data.mdx;return e.createElement(u.Z,{title:s.frontmatter.title,description:s.frontmatter.description||s.excerpt})};function m(n){return e.createElement(k,n,e.createElement(o,n))}},6376:function(n,s,a){var t=a(2982),e=a(7294),p=a(3688),o={"browser-concurrency":{title:"Browser Concurrency",description:"A practical guide to sharing data and coordinating work across browser threads â tabs, workers, and shared memory."},"frontend-system-design":{title:"Frontend System Design Interview Prep",description:"A complete guide to acing frontend system design interviews â from the RADIO framework to real-world component designs asked at FAANG."}};s.Z=function(n){var s=n.seriesSlug,a=n.currentSlug,c=n.seriesPosts;if(!s||!c||0===c.length)return null;var l=o[s]||{title:s,description:""},u=(0,t.Z)(c).sort((function(n,s){return n.seriesOrder-s.seriesOrder})),i=u.findIndex((function(n){return n.slug===a})),r=i>=0?"Part "+(i+1)+" of "+u.length:u.length+" articles";
1return e.createElement("nav",{"aria-label":l.title+" series navigation",style:{borderLeft:"4px solid #4f46e5",background:"#f0f4ff",borderRadius:"0 6px 6px 0",padding:"1rem 1.25rem",marginBottom:"2rem",fontFamily:"var(--fontFamily-sans, system-ui, sans-serif)"}},e.createElement("p",{style:{margin:"0 0 0.75rem 0",fontSize:"0.95rem",fontWeight:700,color:"#1e1b4b",letterSpacing:"-0.01em"}},"ð ",l.title," â ",r),e.createElement("ol",{style:{listStyle:"none",padding:0,margin:"0 0 0.75rem 0"}},u.map((function(n,s){var t=n.slug===a,o=s<i,c={marginBottom:"0.35rem",fontSize:"0.9rem",display:"flex",alignItems:"baseline",gap:"0.4rem"},l=t?"â":o?"â":"  ",u={flexShrink:0,width:"1.2em",color:t?"#4f46e5":o?"#6b7280":"#9ca3af",fontWeight:t?700:400};return t?e.createElement("li",{key:n.slug,style:c,"aria-current":"page"},e.createElement("span",{style:u},l),e.createElement("strong",{style:{color:"#1e1b4b"}},s+1,". ",n.title)):e.createElement("li",{key:n.slug,style:c},e.createElement("span",{style:u},l),e.createElement(p.Link,{to:n.slug,style:{color:o?"#6b7280":"#4f46e5",textDecoration:"none"}},s+1,". ",n.title))}))),e.createElement(p.Link,{to:"/series/"+s+"/",style:{fontSize:"0.85rem",color:"#4f46e5",textDecoration:"none",fontWeight:600}},"View all articles in this series â"))}},4992:function(n,s,a){var t=a(7294);s.Z=function(){var n=(0,t.useState)(!1),s=n[0],a=n[1];(0,t.useEffect)((function(){sessionStorage.getItem("hideKofi")&&a(!0)}),[]);return s?null:t.createElement(t.Fragment,null,t.createElement("a",{target:"_blank",rel:"noreferrer",href:"https://ko-fi.com/javascriptbit"},"Donate"),t.createElement("button",{style:{marginLeft:"1em"},onClick:function(n){n.preventDefault(),a(!0),sessionStorage.setItem("hideKofi","true")}},"Hide for now"))}},2198:function(n,s,a){a.d(s,{Z:function(){return l}});var t=a(7294),e=a(3688),p=a(259);var o=function(){var n=t.useState(null),s=n[0],a=n[1];t.useEffect((function(){var n=document.documentElement.getAttribute("data-theme")||"light";a(n)}),[]);return null===s?t.createElement("span",{style:{width:32,display:"inline-block"}}):t.createElement("button",{onClick:function(){var n="dark"===s?"light":"dark";a(n),document.documentElement.setAttribute("data-theme",n);try{localStorage.setItem("jsbit-theme",n)}catch(t){}},"aria-label":"dark"===s?"Switch to light mode":"Switch to dark mode",title:"dark"===s?"Light mode":"Dark mode",style:{background:"none",border:"none",cursor:"pointer",fontSize:"1.2rem",padding:"4px 8px",borderRadius:"6px",lineHeight:1,color:"inherit",opacity:.75,transition:"opacity 0.15s ease"},onMouseEnter:function(n){return n.currentTarget.style.opacity="1"},onMouseLeave:function(n){return n.currentTarget.style.opacity="0.75"}},"dark"===s?"âï¸":"ð")},c={FullscreenContainer:function(n){var s=n.child,a=(0,t.useState)(!1),e=a[0],p=a[1],o=(0,t.useCallback)((function(n){"Enter"===n.key?p(!e):"Escape"===n.key&&p(!1)}),[e]);return t.createElement("div",{className:"fullscreen "+(e?"active":"")},t.createElement("div",{className:"buttons-container"},t.createElement("span",{tabIndex:-1,role:"button",onClick:function(){return p(!e)},onKeyUp:o},t.createElement("img",{src:"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/PjxzdmcgaGVpZ2h0PSIxNHB4IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxNCAxNCIgd2lkdGg9IjE0cHgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c2tldGNoPSJodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2gvbnMiIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48dGl0bGUvPjxkZXNjLz48ZGVmcy8+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBpZD0iUGFnZS0xIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSI+PGcgZmlsbD0iIzAwMDAwMCIgaWQ9IkNvcmUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMTUuMDAwMDAwLCAtMjU3LjAwMDAwMCkiPjxnIGlkPSJmdWxsc2NyZWVuIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMTUuMDAwMDAwLCAyNTcuMDAwMDAwKSI+PHBhdGggZD0iTTIsOSBMMCw5IEwwLDE0IEw1LDE0IEw1LDEyIEwyLDEyIEwyLDkgTDIsOSBaIE0wLDUgTDIsNSBMMiwyIEw1LDIgTDUsMCBMMCwwIEwwLDUgTDAsNSBaIE0xMiwxMiBMOSwxMiBMOSwxNCBMMTQsMTQgTDE0LDkgTDEyLDkgTDEyLDEyIEwxMiwxMiBaIE05LDAgTDksMiBMMTIsMiBMMTIsNSBMMTQsNSBMMTQsMCBMOSwwIEw5LDAgWiIgaWQ9IlNoYXBlIi8+PC9nPjwvZz48L2c+PC9zdmc+",alt:"Toggle Full Screen",color:"currentColor"}))),s)}},l=function(n){var s,a=n.location,l=n.title,u=n.children,i="/"===a.pathname,r=t.useState(2024),k=r[0],d=r[1];return t.useEffect((function(){d((new Date).getFullYear())}),[]),s=i?t.createElement("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"}},t.createElement("h1",{className:"main-heading"},t.createElement(e.Link,{to:"/"},l)),t.createElement(o,null)):t.createElement("div",{style:{display:"flex",alignItems:"center",justifyContent:"space-between"}},t.createElement(e.Link,{className:"header-link-home",to:"/"},l),t.createElement(o,null)),t.createElement(p.Zo,{components:c},t.createElement("div",{className:"global-wrapper","data-is-root-path":i},t.createElement("header",{className:"global-header"},s),t.createElement("main",null,u),t.createElement("footer",null,"© ",k,", Built with"," ",t.createElement("a",{href:"https://www.gatsbyjs.com"},"Gatsby"))))}},9357:function(n,s,a){var t=a(7294),e=a(3688);s.Z=function(n){var s,a,p,o=n.description,c=n.title,l=n.children,u=(0,e.useStaticQuery)("2841359383").site,i=o||u.siteMetadata.description,r=null===(s=u.siteMetadata)||void 0===s?void 0:s.title;return t.createElement(t.Fragment,null,t.createElement("title",null,r?c+" | "+r:c),t.createElement("meta",{name:"description",content:i}),t.createElement("meta",{property:"og:title",content:c}),t.createElement("meta",{property:"og:description",content:i}),t.createElement("meta",{property:"og:type",content:"website"}),t.createElement("meta",{name:"twitter:card",content:"summary"}),t.createElement("meta",{name:"twitter:creator",content:(null===(a=u.siteMetadata)||void 0===a||null===(p=a.social)||void 0===p?void 0:p.twitter)||""}),t.createElement("meta",{name:"twitter:title",content:c}),t.createElement("meta",{name:"twitter:description",content:i}),l)}}}]); 2//# sourceMappingURL=component---src-templates-blog-post-js-content-file-path-opt-build-repo-content-blog-javascript-websockets-deep-dive-index-md-44cf9c539b8ceaf64247.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.