<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <h2 id="websocket-support-in-geode" class="position-relative d-flex align-items-center group"> <span>WebSocket Support in Geode</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="websocket-support-in-geode" aria-haspopup="dialog" aria-label="Share link: WebSocket Support in Geode"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>WebSocket protocol revolutionizes real-time communication between browsers and servers by providing full-duplex, bidirectional channels over a single TCP connection. While Geode primarily uses QUIC for optimal performance, WebSocket support enables seamless integration with web applications, browser-based clients, and environments where QUIC is unavailable. This comprehensive guide explores WebSocket implementation in Geode, covering real-time subscriptions, live dashboards, collaborative editing, security patterns, and production deployment strategies.</p> <h3 id="understanding-websocket-architecture" class="position-relative d-flex align-items-center group"> <span>Understanding WebSocket Architecture</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="understanding-websocket-architecture" aria-haspopup="dialog" aria-label="Share link: Understanding WebSocket Architecture"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p>Traditional HTTP follows a strict request-response model: clients send requests, servers respond, connection closes. This architecture works well for static content but creates significant challenges for real-time applications. Developers resort to inefficient workarounds like polling (repeatedly asking &ldquo;anything new?&rdquo;), long-polling (holding connections open), or Server-Sent Events (one-way server-to-client).</p> <p>WebSocket solves these limitations by establishing a persistent, bidirectional connection. After an initial HTTP handshake to upgrade the connection, both client and server can send messages at any time without request-response overhead. This enables true real-time communication with minimal latency.</p> <p><strong>WebSocket Advantages</strong>:</p> <ul> <li><strong>Bidirectional</strong>: Both client and server can initiate messages</li> <li><strong>Low Latency</strong>: No HTTP request overhead after initial handshake</li> <li><strong>Efficient</strong>: Single persistent connection instead of repeated requests</li> <li><strong>Real-Time</strong>: Server can push updates immediately when data changes</li> <li><strong>Standardized</strong>: RFC 6455 protocol with broad browser and library support</li> </ul> <p><strong>When to Use WebSocket with Geode</strong>:</p> <ul> <li>Browser-based applications requiring real-time updates</li> <li>Live dashboards displaying changing metrics</li> <li>Collaborative editing where multiple users modify shared data</li> <li>Chat applications with instant message delivery</li> <li>Notification systems pushing alerts to clients</li> <li>Event streaming from database changes to UI</li> </ul> <p><strong>When to Use QUIC Instead</strong>:</p> <ul> <li>Backend services and microservices (QUIC provides better performance)</li> <li>Mobile applications (QUIC handles network transitions better)</li> <li>High-throughput scenarios (QUIC&rsquo;s multiplexing excels)</li> <li>Low-latency requirements (QUIC&rsquo;s 0-RTT resumption is faster)</li> </ul> <h3 id="websocket-basics" class="position-relative d-flex align-items-center group"> <span>WebSocket Basics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="websocket-basics" aria-haspopup="dialog" aria-label="Share link: WebSocket Basics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="what-are-websockets" class="position-relative d-flex align-items-center group"> <span>What are WebSockets?</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="what-are-websockets" aria-haspopup="dialog" aria-label="Share link: What are WebSockets?"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>WebSockets provide:</p> <p><strong>Full-Duplex</strong> - Simultaneous bidirectional communication <strong>Low Latency</strong> - Minimal overhead after connection established <strong>Real-Time</strong> - Push updates from server to client <strong>Persistent</strong> - Long-lived connections</p> <h4 id="websocket-vs-http" class="position-relative d-flex align-items-center group"> <span>WebSocket vs HTTP</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="websocket-vs-http" aria-haspopup="dialog" aria-label="Share link: WebSocket vs HTTP"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><table> <thead> <tr> <th>Feature</th> <th>HTTP</th> <th>WebSocket</th> </tr> </thead> <tbody> <tr> <td>Communication</td> <td>Request-Response</td> <td>Bidirectional</td> </tr> <tr> <td>Connection</td> <td>Short-lived</td> <td>Persistent</td> </tr> <tr> <td>Overhead</td> <td>High (headers per request)</td> <td>Low (single handshake)</td> </tr> <tr> <td>Server Push</td> <td>No (polling required)</td> <td>Yes (native)</td> </tr> </tbody> </table> <h3 id="geode-websocket-api" class="position-relative d-flex align-items-center group"> <span>Geode WebSocket API</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="geode-websocket-api" aria-haspopup="dialog" aria-label="Share link: Geode WebSocket API"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="connecting-via-websocket" class="position-relative d-flex align-items-center group"> <span>Connecting via WebSocket</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="connecting-via-websocket" aria-haspopup="dialog" aria-label="Share link: Connecting via WebSocket"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Establish WebSocket connection:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// JavaScript client </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s1">&#39;wss://geode.example.com:8443/ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Connected to Geode&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Authenticate </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;AUTH&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">token</span><span class="o">:</span> <span class="s1">&#39;your-jwt-token&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Received:&#39;</span><span class="p">,</span> <span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">ws</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;WebSocket error:&#39;</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">ws</span><span class="p">.</span><span class="nx">onclose</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Disconnected from Geode&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></div> <h4 id="executing-queries" class="position-relative d-flex align-items-center group"> <span>Executing Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="executing-queries" aria-haspopup="dialog" aria-label="Share link: Executing Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Run GQL queries over WebSocket:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">executeQuery</span><span class="p">(</span><span class="nx">query</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">request</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;QUERY&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="nx">generateRequestId</span><span class="p">(),</span> </span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="o">:</span> <span class="nx">query</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">parameters</span><span class="o">:</span> <span class="nx">params</span> <span class="o">||</span> <span class="p">{}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">request</span><span class="p">));</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Execute query </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">executeQuery</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;MATCH (p:Person) WHERE p.age &gt; $age RETURN p&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">age</span><span class="o">:</span> <span class="mi">18</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Handle response </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;RESULT&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Query results:&#39;</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;ERROR&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;Query error:&#39;</span><span class="p">,</span> <span class="nx">response</span><span class="p">.</span><span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></div> <h4 id="subscription-queries" class="position-relative d-flex align-items-center group"> <span>Subscription Queries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="subscription-queries" aria-haspopup="dialog" aria-label="Share link: Subscription Queries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Subscribe to real-time updates:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Subscribe to changes </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">subscribeToUserUpdates</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;SUBSCRIBE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;user-updates&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="o">:</span> <span class="s1">&#39;SUBSCRIBE TO users WHERE age &gt; 18&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Receive subscription updates </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;UPDATE&#39;</span> <span class="o">&amp;&amp;</span> <span class="nx">message</span><span class="p">.</span><span class="nx">subscription</span> <span class="o">===</span> <span class="s1">&#39;user-updates&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;User updated:&#39;</span><span class="p">,</span> <span class="nx">message</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">updateUI</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Unsubscribe </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">unsubscribe</span> <span class="o">=</span> <span class="p">(</span><span class="nx">id</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;UNSUBSCRIBE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="nx">id</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></div> <h3 id="use-cases" class="position-relative d-flex align-items-center group"> <span>Use Cases</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="use-cases" aria-haspopup="dialog" aria-label="Share link: Use Cases"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="live-dashboards" class="position-relative d-flex align-items-center group"> <span>Live Dashboards</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="live-dashboards" aria-haspopup="dialog" aria-label="Share link: Live Dashboards"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Update dashboards in real-time:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">LiveDashboard</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">wsUrl</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="nx">wsUrl</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">setupHandlers</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">setupHandlers</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Subscribe to metrics </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">(</span><span class="s1">&#39;system-metrics&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;SELECT * FROM metrics EMIT CHANGES&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;UPDATE&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">updateMetric</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">subscribe</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">query</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;SUBSCRIBE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="nx">id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="o">:</span> <span class="nx">query</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">updateMetric</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Update dashboard UI </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">&#39;cpu-usage&#39;</span><span class="p">).</span><span class="nx">textContent</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">cpu</span> <span class="o">+</span> <span class="s1">&#39;%&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">&#39;memory-usage&#39;</span><span class="p">).</span><span class="nx">textContent</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">memory</span> <span class="o">+</span> <span class="s1">&#39;%&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">dashboard</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">LiveDashboard</span><span class="p">(</span><span class="s1">&#39;wss://geode.local:8443/ws&#39;</span><span class="p">);</span> </span></span></code></pre></div> <h4 id="collaborative-editing" class="position-relative d-flex align-items-center group"> <span>Collaborative Editing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="collaborative-editing" aria-haspopup="dialog" aria-label="Share link: Collaborative Editing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Enable real-time collaboration:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">CollaborativeEditor</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">documentId</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">documentId</span> <span class="o">=</span> <span class="nx">documentId</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s1">&#39;wss://geode.local:8443/ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">setupSync</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">setupSync</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Join collaboration session </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;JOIN_SESSION&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">document_id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">documentId</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;EDIT&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">applyRemoteEdit</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">edit</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;USER_JOINED&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">showUser</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">user</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">sendEdit</span><span class="p">(</span><span class="nx">edit</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;EDIT&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">document_id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">documentId</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">edit</span><span class="o">:</span> <span class="nx">edit</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">applyRemoteEdit</span><span class="p">(</span><span class="nx">edit</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Apply edit from other user </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">editor</span><span class="p">.</span><span class="nx">applyChange</span><span class="p">(</span><span class="nx">edit</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="chat-applications" class="position-relative d-flex align-items-center group"> <span>Chat Applications</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="chat-applications" aria-haspopup="dialog" aria-label="Share link: Chat Applications"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Build real-time chat:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">ChatClient</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">roomId</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">roomId</span> <span class="o">=</span> <span class="nx">roomId</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="s1">&#39;wss://geode.local:8443/ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">setupChat</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">setupChat</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Join chat room </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;JOIN_ROOM&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">room_id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">roomId</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;MESSAGE&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">displayMessage</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;TYPING&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">showTypingIndicator</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">user</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">sendMessage</span><span class="p">(</span><span class="nx">text</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;MESSAGE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">room_id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">roomId</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">text</span><span class="o">:</span> <span class="nx">text</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">timestamp</span><span class="o">:</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">sendTypingIndicator</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;TYPING&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">room_id</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">roomId</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="connection-management" class="position-relative d-flex align-items-center group"> <span>Connection Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="connection-management" aria-haspopup="dialog" aria-label="Share link: Connection Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Handle connection lifecycle:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">ReliableWebSocket</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">url</span> <span class="o">=</span> <span class="nx">url</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">reconnectDelay</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">maxReconnectDelay</span> <span class="o">=</span> <span class="mi">30000</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connect</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">connect</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">url</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onopen</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Connected&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">reconnectDelay</span> <span class="o">=</span> <span class="mi">1000</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">onopen</span><span class="o">?</span><span class="p">.();</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onclose</span> <span class="o">=</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Disconnected, reconnecting...&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">reconnectDelay</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">reconnectDelay</span> <span class="o">*</span> <span class="mi">2</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">maxReconnectDelay</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connect</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> <span class="k">this</span><span class="p">.</span><span class="nx">reconnectDelay</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onerror</span> <span class="o">=</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">&#39;WebSocket error:&#39;</span><span class="p">,</span> <span class="nx">error</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">onmessage</span><span class="o">?</span><span class="p">.(</span><span class="nx">event</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">send</span><span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">===</span> <span class="nx">WebSocket</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="s1">&#39;WebSocket not connected&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="message-acknowledgment" class="position-relative d-flex align-items-center group"> <span>Message Acknowledgment</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="message-acknowledgment" aria-haspopup="dialog" aria-label="Share link: Message Acknowledgment"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Ensure reliable delivery:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">AcknowledgedWebSocket</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pendingMessages</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">messageId</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">setupHandlers</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">setupHandlers</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">msg</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;ACK&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Remove from pending </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">pendingMessages</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">message_id</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">msg</span><span class="p">.</span><span class="nx">type</span> <span class="o">===</span> <span class="s1">&#39;MESSAGE&#39;</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Send acknowledgment </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;ACK&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">message_id</span><span class="o">:</span> <span class="nx">msg</span><span class="p">.</span><span class="nx">id</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleMessage</span><span class="p">(</span><span class="nx">msg</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">send</span><span class="p">(</span><span class="nx">data</span><span class="p">,</span> <span class="nx">timeout</span> <span class="o">=</span> <span class="mi">5000</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="o">++</span><span class="k">this</span><span class="p">.</span><span class="nx">messageId</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="nx">id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;MESSAGE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="o">:</span> <span class="nx">data</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Store for retry </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">this</span><span class="p">.</span><span class="nx">pendingMessages</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="o">:</span> <span class="nx">message</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">resolve</span><span class="o">:</span> <span class="nx">resolve</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">reject</span><span class="o">:</span> <span class="nx">reject</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">timeout</span><span class="o">:</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pendingMessages</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">reject</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Message timeout&#39;</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> <span class="nx">timeout</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">message</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="advanced-websocket-patterns" class="position-relative d-flex align-items-center group"> <span>Advanced WebSocket Patterns</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="advanced-websocket-patterns" aria-haspopup="dialog" aria-label="Share link: Advanced WebSocket Patterns"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="request-response-pattern" class="position-relative d-flex align-items-center group"> <span>Request-Response Pattern</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="request-response-pattern" aria-haspopup="dialog" aria-label="Share link: Request-Response Pattern"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implement request-response over WebSocket:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">WebSocketRPC</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pending</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">requestId</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">pending</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">pending</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">pending</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">pending</span><span class="p">.</span><span class="nx">reject</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">error</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">pending</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">result</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pending</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">id</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">call</span><span class="p">(</span><span class="nx">method</span><span class="p">,</span> <span class="nx">params</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nb">Promise</span><span class="p">((</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">id</span> <span class="o">=</span> <span class="o">++</span><span class="k">this</span><span class="p">.</span><span class="nx">requestId</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pending</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="p">{</span> <span class="nx">resolve</span><span class="p">,</span> <span class="nx">reject</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">jsonrpc</span><span class="o">:</span> <span class="s1">&#39;2.0&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">id</span><span class="o">:</span> <span class="nx">id</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">method</span><span class="o">:</span> <span class="nx">method</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">params</span><span class="o">:</span> <span class="nx">params</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Timeout after 30 seconds </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">pending</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">pending</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">id</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">reject</span><span class="p">(</span><span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">&#39;Request timeout&#39;</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> <span class="mi">30000</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Usage </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">rpc</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocketRPC</span><span class="p">(</span><span class="s1">&#39;wss://geode.example.com/ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">rpc</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">gql</span><span class="o">:</span> <span class="s1">&#39;MATCH (p:Person) RETURN COUNT(p)&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">params</span><span class="o">:</span> <span class="p">{}</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Count:&#39;</span><span class="p">,</span> <span class="nx">result</span><span class="p">.</span><span class="nx">data</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nx">count</span><span class="p">);</span> </span></span></code></pre></div> <h4 id="multiplexed-channels" class="position-relative d-flex align-items-center group"> <span>Multiplexed Channels</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="multiplexed-channels" aria-haspopup="dialog" aria-label="Share link: Multiplexed Channels"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Support multiple logical channels over one WebSocket:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">MultiplexedWebSocket</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">channels</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">channel</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">channels</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">channel</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">channel</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">channel</span><span class="p">.</span><span class="nx">onmessage</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">createChannel</span><span class="p">(</span><span class="nx">name</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">channel</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">name</span><span class="o">:</span> <span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">send</span><span class="o">:</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">channel</span><span class="o">:</span> <span class="nx">name</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="o">:</span> <span class="nx">data</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">onmessage</span><span class="o">:</span> <span class="kc">null</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">close</span><span class="o">:</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">channels</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">name</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">channels</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">channel</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">channel</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Usage </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">mux</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MultiplexedWebSocket</span><span class="p">(</span><span class="s1">&#39;wss://geode.example.com/ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Create separate channels for different purposes </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">queryChannel</span> <span class="o">=</span> <span class="nx">mux</span><span class="p">.</span><span class="nx">createChannel</span><span class="p">(</span><span class="s1">&#39;queries&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">notificationChannel</span> <span class="o">=</span> <span class="nx">mux</span><span class="p">.</span><span class="nx">createChannel</span><span class="p">(</span><span class="s1">&#39;notifications&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">metricsChannel</span> <span class="o">=</span> <span class="nx">mux</span><span class="p">.</span><span class="nx">createChannel</span><span class="p">(</span><span class="s1">&#39;metrics&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">queryChannel</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Query result:&#39;</span><span class="p">,</span> <span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">notificationChannel</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">showNotification</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nx">metricsChannel</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">updateDashboard</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">metrics</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span></code></pre></div> <h4 id="binary-protocol-support" class="position-relative d-flex align-items-center group"> <span>Binary Protocol Support</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="binary-protocol-support" aria-haspopup="dialog" aria-label="Share link: Binary Protocol Support"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Send binary data over WebSocket for efficiency:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">BinaryWebSocket</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">binaryType</span> <span class="o">=</span> <span class="s1">&#39;arraybuffer&#39;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">onmessage</span> <span class="o">=</span> <span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span> <span class="k">instanceof</span> <span class="nx">ArrayBuffer</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleBinaryMessage</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">handleTextMessage</span><span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">sendBinaryQuery</span><span class="p">(</span><span class="nx">query</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Encode query as binary protocol </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">encoder</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">TextEncoder</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">queryBytes</span> <span class="o">=</span> <span class="nx">encoder</span><span class="p">.</span><span class="nx">encode</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Create header: [version(1), type(1), length(4)] </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">header</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ArrayBuffer</span><span class="p">(</span><span class="mi">6</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DataView</span><span class="p">(</span><span class="nx">header</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">view</span><span class="p">.</span><span class="nx">setUint8</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// Protocol version </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">view</span><span class="p">.</span><span class="nx">setUint8</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// Message type: QUERY </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">view</span><span class="p">.</span><span class="nx">setUint32</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">queryBytes</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Concatenate header and query </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Uint8Array</span><span class="p">(</span><span class="nx">header</span><span class="p">.</span><span class="nx">byteLength</span> <span class="o">+</span> <span class="nx">queryBytes</span><span class="p">.</span><span class="nx">length</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="k">new</span> <span class="nx">Uint8Array</span><span class="p">(</span><span class="nx">header</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">queryBytes</span><span class="p">,</span> <span class="nx">header</span><span class="p">.</span><span class="nx">byteLength</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">message</span><span class="p">.</span><span class="nx">buffer</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">handleBinaryMessage</span><span class="p">(</span><span class="nx">buffer</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">view</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">DataView</span><span class="p">(</span><span class="nx">buffer</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">version</span> <span class="o">=</span> <span class="nx">view</span><span class="p">.</span><span class="nx">getUint8</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">type</span> <span class="o">=</span> <span class="nx">view</span><span class="p">.</span><span class="nx">getUint8</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">length</span> <span class="o">=</span> <span class="nx">view</span><span class="p">.</span><span class="nx">getUint32</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Decode based on type </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="nx">type</span> <span class="o">===</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// RESULT </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">decoder</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">TextDecoder</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">payload</span> <span class="o">=</span> <span class="nx">buffer</span><span class="p">.</span><span class="nx">slice</span><span class="p">(</span><span class="mi">6</span><span class="p">,</span> <span class="mi">6</span> <span class="o">+</span> <span class="nx">length</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">decoder</span><span class="p">.</span><span class="nx">decode</span><span class="p">(</span><span class="nx">payload</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">onresult</span><span class="p">(</span><span class="nx">result</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="production-deployment" class="position-relative d-flex align-items-center group"> <span>Production Deployment</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="production-deployment" aria-haspopup="dialog" aria-label="Share link: Production Deployment"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="load-balancing-websockets" class="position-relative d-flex align-items-center group"> <span>Load Balancing WebSockets</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="load-balancing-websockets" aria-haspopup="dialog" aria-label="Share link: Load Balancing WebSockets"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Configure load balancer for WebSocket sticky sessions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="c1"># nginx.conf </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">upstream</span> <span class="s">geode_websockets</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kn">ip_hash</span><span class="p">;</span> <span class="c1"># Sticky sessions based on client IP </span></span></span><span class="line"><span class="cl"><span class="c1"></span> </span></span><span class="line"><span class="cl"> <span class="kn">server</span> <span class="n">geode-1.internal</span><span class="p">:</span><span class="mi">8443</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">server</span> <span class="n">geode-2.internal</span><span class="p">:</span><span class="mi">8443</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">server</span> <span class="n">geode-3.internal</span><span class="p">:</span><span class="mi">8443</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">server_name</span> <span class="s">geode.example.com</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kn">ssl_certificate</span> <span class="s">/etc/nginx/ssl/cert.pem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">ssl_certificate_key</span> <span class="s">/etc/nginx/ssl/key.pem</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kn">location</span> <span class="s">/ws</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_pass</span> <span class="s">https://geode_websockets</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_http_version</span> <span class="mi">1</span><span class="s">.1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># WebSocket upgrade headers </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kn">proxy_set_header</span> <span class="s">Upgrade</span> <span class="nv">$http_upgrade</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_set_header</span> <span class="s">Connection</span> <span class="s">&#34;upgrade&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_set_header</span> <span class="s">Host</span> <span class="nv">$host</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Timeouts for long-lived connections </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kn">proxy_connect_timeout</span> <span class="s">7d</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_send_timeout</span> <span class="s">7d</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kn">proxy_read_timeout</span> <span class="s">7d</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Disable buffering </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kn">proxy_buffering</span> <span class="no">off</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="connection-scaling" class="position-relative d-flex align-items-center group"> <span>Connection Scaling</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="connection-scaling" aria-haspopup="dialog" aria-label="Share link: Connection Scaling"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Handle thousands of concurrent WebSocket connections:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Server-side connection management </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">class</span> <span class="nx">WebSocketPool</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">maxConnections</span> <span class="o">=</span> <span class="mi">10000</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connectionTimeout</span> <span class="o">=</span> <span class="mi">300000</span><span class="p">;</span> <span class="c1">// 5 minutes </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">addConnection</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">ws</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Enforce connection limit </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">size</span> <span class="o">&gt;=</span> <span class="k">this</span><span class="p">.</span><span class="nx">maxConnections</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1008</span><span class="p">,</span> <span class="s1">&#39;Server at capacity&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Close existing connection for same user </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kr">const</span> <span class="nx">existing</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">userId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">existing</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">existing</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s1">&#39;Replaced by new connection&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">ws</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// Set idle timeout </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">ws</span><span class="p">.</span><span class="nx">lastActivity</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">timeout</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span> <span class="o">-</span> <span class="nx">ws</span><span class="p">.</span><span class="nx">lastActivity</span> <span class="o">&gt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">connectionTimeout</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s1">&#39;Idle timeout&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">userId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> <span class="k">this</span><span class="p">.</span><span class="nx">connectionTimeout</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;message&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">lastActivity</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;close&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">clearTimeout</span><span class="p">(</span><span class="nx">ws</span><span class="p">.</span><span class="nx">timeout</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="nx">userId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">broadcast</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="p">[</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">ws</span><span class="p">]</span> <span class="k">of</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">ws</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">===</span> <span class="nx">WebSocket</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">sendToUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">message</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">ws</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">userId</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">ws</span> <span class="o">&amp;&amp;</span> <span class="nx">ws</span><span class="p">.</span><span class="nx">readyState</span> <span class="o">===</span> <span class="nx">WebSocket</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">message</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">getStats</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">total_connections</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">size</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">capacity_used</span><span class="o">:</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">size</span> <span class="o">/</span> <span class="k">this</span><span class="p">.</span><span class="nx">maxConnections</span> <span class="o">*</span> <span class="mi">100</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="s1">&#39;%&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h4 id="security-hardening" class="position-relative d-flex align-items-center group"> <span>Security Hardening</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-hardening" aria-haspopup="dialog" aria-label="Share link: Security Hardening"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Implement WebSocket security best practices:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Authentication middleware </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">function</span> <span class="nx">authenticateWebSocket</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">ws</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">token</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">URL</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">url</span><span class="p">,</span> <span class="s1">&#39;ws://localhost&#39;</span><span class="p">).</span><span class="nx">searchParams</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;token&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">token</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1008</span><span class="p">,</span> <span class="s1">&#39;Authentication required&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">decoded</span> <span class="o">=</span> <span class="nx">jwt</span><span class="p">.</span><span class="nx">verify</span><span class="p">(</span><span class="nx">token</span><span class="p">,</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">JWT_SECRET</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">req</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">decoded</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1008</span><span class="p">,</span> <span class="s1">&#39;Invalid token&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Rate limiting </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">rateLimiter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Map</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">checkRateLimit</span><span class="p">(</span><span class="nx">userId</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">now</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">userLimit</span> <span class="o">=</span> <span class="nx">rateLimiter</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">userId</span><span class="p">)</span> <span class="o">||</span> <span class="p">{</span> <span class="nx">count</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">resetTime</span><span class="o">:</span> <span class="nx">now</span> <span class="o">+</span> <span class="mi">60000</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">now</span> <span class="o">&gt;</span> <span class="nx">userLimit</span><span class="p">.</span><span class="nx">resetTime</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// Reset counter </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">rateLimiter</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="p">{</span> <span class="nx">count</span><span class="o">:</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">resetTime</span><span class="o">:</span> <span class="nx">now</span> <span class="o">+</span> <span class="mi">60000</span> <span class="p">});</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">userLimit</span><span class="p">.</span><span class="nx">count</span> <span class="o">&gt;=</span> <span class="mi">100</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 100 messages per minute </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="kc">false</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">userLimit</span><span class="p">.</span><span class="nx">count</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Message validation </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">function</span> <span class="nx">validateMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">schema</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;object&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">required</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;type&#39;</span><span class="p">,</span> <span class="s1">&#39;data&#39;</span><span class="p">],</span> </span></span><span class="line"><span class="cl"> <span class="nx">properties</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;string&#39;</span><span class="p">,</span> <span class="kr">enum</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;QUERY&#39;</span><span class="p">,</span> <span class="s1">&#39;SUBSCRIBE&#39;</span><span class="p">,</span> <span class="s1">&#39;UNSUBSCRIBE&#39;</span><span class="p">]</span> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="o">:</span> <span class="p">{</span> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;object&#39;</span> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">maxProperties</span><span class="o">:</span> <span class="mi">3</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">validate</span> <span class="o">=</span> <span class="nx">ajv</span><span class="p">.</span><span class="nx">compile</span><span class="p">(</span><span class="nx">schema</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">validate</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Apply security layers </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">wss</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;connection&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">ws</span><span class="p">,</span> <span class="nx">req</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">authenticateWebSocket</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">ws</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">on</span><span class="p">(</span><span class="s1">&#39;message&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">checkRateLimit</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">.</span><span class="nx">id</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;ERROR&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">error</span><span class="o">:</span> <span class="s1">&#39;Rate limit exceeded&#39;</span> </span></span><span class="line"><span class="cl"> <span class="p">}));</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">message</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">message</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1003</span><span class="p">,</span> <span class="s1">&#39;Invalid JSON&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">validateMessage</span><span class="p">(</span><span class="nx">message</span><span class="p">))</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">ws</span><span class="p">.</span><span class="nx">close</span><span class="p">(</span><span class="mi">1003</span><span class="p">,</span> <span class="s1">&#39;Invalid message format&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">handleMessage</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">user</span><span class="p">,</span> <span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span></code></pre></div> <h3 id="monitoring-and-observability" class="position-relative d-flex align-items-center group"> <span>Monitoring and Observability</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="monitoring-and-observability" aria-haspopup="dialog" aria-label="Share link: Monitoring and Observability"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="metrics-collection" class="position-relative d-flex align-items-center group"> <span>Metrics Collection</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="metrics-collection" aria-haspopup="dialog" aria-label="Share link: Metrics Collection"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Track WebSocket performance metrics:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">metrics</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">connections_total</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">connections_active</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">messages_sent</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">messages_received</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">bytes_sent</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">bytes_received</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">errors_total</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">recordConnection</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections_total</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections_active</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">recordDisconnection</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">connections_active</span><span class="o">--</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">recordMessageSent</span><span class="p">(</span><span class="nx">size</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">messages_sent</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">bytes_sent</span> <span class="o">+=</span> <span class="nx">size</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">recordMessageReceived</span><span class="p">(</span><span class="nx">size</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">messages_received</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">bytes_received</span> <span class="o">+=</span> <span class="nx">size</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">recordError</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">errors_total</span><span class="o">++</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">getStats</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">connections</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">total</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections_total</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">active</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">connections_active</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">messages</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">sent</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">messages_sent</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">received</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">messages_received</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">bandwidth</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">sent_mb</span><span class="o">:</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">bytes_sent</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">2</span><span class="p">),</span> </span></span><span class="line"><span class="cl"> <span class="nx">received_mb</span><span class="o">:</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">bytes_received</span> <span class="o">/</span> <span class="mi">1024</span> <span class="o">/</span> <span class="mi">1024</span><span class="p">).</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">errors</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">errors_total</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Export to Prometheus </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/metrics&#39;</span><span class="p">,</span> <span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">stats</span> <span class="o">=</span> <span class="nx">metrics</span><span class="p">.</span><span class="nx">getStats</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="nx">res</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;Content-Type&#39;</span><span class="p">,</span> <span class="s1">&#39;text/plain&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nx">res</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="sb">` </span></span></span><span class="line"><span class="cl"><span class="sb"># HELP websocket_connections_active Active WebSocket connections </span></span></span><span class="line"><span class="cl"><span class="sb"># TYPE websocket_connections_active gauge </span></span></span><span class="line"><span class="cl"><span class="sb">websocket_connections_active </span><span class="si">${</span><span class="nx">stats</span><span class="p">.</span><span class="nx">connections</span><span class="p">.</span><span class="nx">active</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"># HELP websocket_messages_sent_total Total messages sent </span></span></span><span class="line"><span class="cl"><span class="sb"># TYPE websocket_messages_sent_total counter </span></span></span><span class="line"><span class="cl"><span class="sb">websocket_messages_sent_total </span><span class="si">${</span><span class="nx">stats</span><span class="p">.</span><span class="nx">messages</span><span class="p">.</span><span class="nx">sent</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"># HELP websocket_errors_total Total WebSocket errors </span></span></span><span class="line"><span class="cl"><span class="sb"># TYPE websocket_errors_total counter </span></span></span><span class="line"><span class="cl"><span class="sb">websocket_errors_total </span><span class="si">${</span><span class="nx">stats</span><span class="p">.</span><span class="nx">errors</span><span class="si">}</span><span class="sb"> </span></span></span><span class="line"><span class="cl"><span class="sb"> `</span><span class="p">.</span><span class="nx">trim</span><span class="p">());</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span></code></pre></div> <h3 id="performance-optimization" class="position-relative d-flex align-items-center group"> <span>Performance Optimization</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-optimization" aria-haspopup="dialog" aria-label="Share link: Performance Optimization"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="message-batching" class="position-relative d-flex align-items-center group"> <span>Message Batching</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="message-batching" aria-haspopup="dialog" aria-label="Share link: Message Batching"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Batch multiple updates for efficiency:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">MessageBatcher</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">constructor</span><span class="p">(</span><span class="nx">ws</span><span class="p">,</span> <span class="nx">flushInterval</span> <span class="o">=</span> <span class="mi">100</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span> <span class="o">=</span> <span class="nx">ws</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">queue</span> <span class="o">=</span> <span class="p">[];</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">flushInterval</span> <span class="o">=</span> <span class="nx">flushInterval</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">timer</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">enqueue</span><span class="p">(</span><span class="nx">message</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">timer</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">timer</span> <span class="o">=</span> <span class="nx">setTimeout</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">flush</span><span class="p">();</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> <span class="k">this</span><span class="p">.</span><span class="nx">flushInterval</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="nx">flush</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">queue</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">batch</span> <span class="o">=</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;BATCH&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">messages</span><span class="o">:</span> <span class="k">this</span><span class="p">.</span><span class="nx">queue</span> </span></span><span class="line"><span class="cl"> <span class="p">};</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">ws</span><span class="p">.</span><span class="nx">send</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">batch</span><span class="p">));</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">queue</span> <span class="o">=</span> <span class="p">[];</span> </span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">timer</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Usage </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">batcher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MessageBatcher</span><span class="p">(</span><span class="nx">ws</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="c1">// Instead of sending individually </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">update</span> <span class="k">of</span> <span class="nx">updates</span><span class="p">)</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">batcher</span><span class="p">.</span><span class="nx">enqueue</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;UPDATE&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">data</span><span class="o">:</span> <span class="nx">update</span> </span></span><span class="line"><span class="cl"> <span class="p">});</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="c1">// Batched message sent after 100ms </span></span></span></code></pre></div> <h4 id="compression" class="position-relative d-flex align-items-center group"> <span>Compression</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="compression" aria-haspopup="dialog" aria-label="Share link: Compression"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Enable WebSocket compression (permessage-deflate):</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">WebSocket</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;ws&#39;</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">wss</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">WebSocket</span><span class="p">.</span><span class="nx">Server</span><span class="p">({</span> </span></span><span class="line"><span class="cl"> <span class="nx">port</span><span class="o">:</span> <span class="mi">8443</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">perMessageDeflate</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">zlibDeflateOptions</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">chunkSize</span><span class="o">:</span> <span class="mi">1024</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">memLevel</span><span class="o">:</span> <span class="mi">7</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">level</span><span class="o">:</span> <span class="mi">3</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">zlibInflateOptions</span><span class="o">:</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">chunkSize</span><span class="o">:</span> <span class="mi">10</span> <span class="o">*</span> <span class="mi">1024</span> </span></span><span class="line"><span class="cl"> <span class="p">},</span> </span></span><span class="line"><span class="cl"> <span class="nx">clientNoContextTakeover</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">serverNoContextTakeover</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">serverMaxWindowBits</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">concurrencyLimit</span><span class="o">:</span> <span class="mi">10</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nx">threshold</span><span class="o">:</span> <span class="mi">1024</span> <span class="c1">// Only compress messages &gt; 1KB </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="p">});</span> </span></span></code></pre></div><p>Compression typically reduces bandwidth by 60-80% for text data.</p> <h3 id="troubleshooting-websocket-issues" class="position-relative d-flex align-items-center group"> <span>Troubleshooting WebSocket Issues</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting-websocket-issues" aria-haspopup="dialog" aria-label="Share link: Troubleshooting WebSocket Issues"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><p><strong>Connection Drops Frequently</strong>: Check firewall timeout settings. Implement heartbeat/ping-pong to keep connection alive. Verify proxy timeouts are configured correctly.</p> <p><strong>High Latency</strong>: Enable compression for large messages. Reduce message size through batching. Check network congestion between client and server.</p> <p><strong>Memory Leaks</strong>: Ensure event listeners are properly removed on disconnect. Clear timeouts and intervals when connection closes. Monitor memory usage of WebSocket server process.</p> <p><strong>Authentication Failures</strong>: Verify token is passed correctly in connection URL or initial message. Check token expiration and renewal logic. Ensure CORS is configured for WebSocket endpoint.</p> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><strong><a href="/tags/real-time/" >Real-Time</a> </strong>: Real-time data processing</li> <li><strong><a href="/tags/streaming/" >Streaming</a> </strong>: Event streaming</li> <li><strong><a href="/tags/pubsub/" >Pub/Sub</a> </strong>: Publish-subscribe messaging</li> <li><strong><a href="/tags/events/" >Events</a> </strong>: Event-driven architecture</li> <li><strong><a href="/tags/networking/" >Networking</a> </strong>: Network architecture</li> <li><strong><a href="/tags/security/" >Security</a> </strong>: Security best practices</li> <li><strong><a href="/tags/monitoring/" >Monitoring</a> </strong>: Application monitoring</li> <li><strong><a href="/tags/performance/" >Performance</a> </strong>: Performance optimization</li> </ul> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><strong><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket" aria-label="WebSocket API (MDN) – opens in new window" target="_blank" rel="noopener noreferrer" >WebSocket API (MDN) <span aria-hidden="true" class="external-icon">↗</span> </a> </strong>: Browser WebSocket documentation</li> <li><strong><a href="https://socket.io/" aria-label="Socket.IO – opens in new window" target="_blank" rel="noopener noreferrer" >Socket.IO <span aria-hidden="true" class="external-icon">↗</span> </a> </strong>: Popular WebSocket library with fallbacks</li> <li><strong><a href="https://tools.ietf.org/html/rfc6455" aria-label="WebSocket Protocol RFC 6455 – opens in new window" target="_blank" rel="noopener noreferrer" >WebSocket Protocol RFC 6455 <span aria-hidden="true" class="external-icon">↗</span> </a> </strong>: Official WebSocket specification</li> <li><strong>Geode WebSocket Guide</strong>: <code>/docs/networking/websockets/</code></li> <li><strong>Real-Time Subscriptions</strong>: <code>/docs/features/subscriptions/</code></li> <li><strong>Connection Management</strong>: <code>/docs/operations/connection-management/</code></li> </ul>

Related Articles

No articles found with this tag yet.

Back to Home