<!-- 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 “anything new?”), 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’s multiplexing excels)</li>
<li>Low-latency requirements (QUIC’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">'wss://geode.example.com:8443/ws'</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">=></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">'Connected to Geode'</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">'AUTH'</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">'your-jwt-token'</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">=></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">'Received:'</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">=></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">'WebSocket error:'</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">=></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">'Disconnected from Geode'</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">'QUERY'</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">'MATCH (p:Person) WHERE p.age > $age RETURN p'</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">=></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">'RESULT'</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">'Query results:'</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">'ERROR'</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">'Query 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></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">=></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">'SUBSCRIBE'</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">'user-updates'</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">'SUBSCRIBE TO users WHERE age > 18'</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">=></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">'UPDATE'</span> <span class="o">&&</span> <span class="nx">message</span><span class="p">.</span><span class="nx">subscription</span> <span class="o">===</span> <span class="s1">'user-updates'</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">'User updated:'</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">=></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">'UNSUBSCRIBE'</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">=></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">'system-metrics'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'SELECT * FROM metrics EMIT CHANGES'</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">=></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">'UPDATE'</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">'SUBSCRIBE'</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">'cpu-usage'</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">'%'</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">'memory-usage'</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">'%'</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">'wss://geode.local:8443/ws'</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">'wss://geode.local:8443/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">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">=></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">'JOIN_SESSION'</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">=></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">'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">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">'USER_JOINED'</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">'EDIT'</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">'wss://geode.local:8443/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">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">=></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">'JOIN_ROOM'</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">=></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">'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">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">'TYPING'</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">'MESSAGE'</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">'TYPING'</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">=></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">'Connected'</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">=></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">'Disconnected, reconnecting...'</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">=></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">=></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">'WebSocket error:'</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">=></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">'WebSocket not connected'</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">=></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">'ACK'</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">'MESSAGE'</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">'ACK'</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">'MESSAGE'</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">=></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">=></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">'Message timeout'</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">=></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">=></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">'2.0'</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">=></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">'Request 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 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">'wss://geode.example.com/ws'</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">'query'</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">'MATCH (p:Person) RETURN COUNT(p)'</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">'Count:'</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">=></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">=></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">=></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">'wss://geode.example.com/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">// 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">'queries'</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">'notifications'</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">'metrics'</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">=></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">'Query result:'</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">=></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">=></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">'arraybuffer'</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">=></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">"upgrade"</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">>=</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">'Server at capacity'</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">'Replaced by new connection'</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">=></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">></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">'Idle 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 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">'message'</span><span class="p">,</span> <span class="p">()</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">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">'close'</span><span class="p">,</span> <span class="p">()</span> <span class="p">=></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">&&</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">'%'</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">'ws://localhost'</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">'token'</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">'Authentication required'</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">'Invalid token'</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">></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">>=</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">'object'</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">'type'</span><span class="p">,</span> <span class="s1">'data'</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">'string'</span><span class="p">,</span> <span class="kr">enum</span><span class="o">:</span> <span class="p">[</span><span class="s1">'QUERY'</span><span class="p">,</span> <span class="s1">'SUBSCRIBE'</span><span class="p">,</span> <span class="s1">'UNSUBSCRIBE'</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">'object'</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">'connection'</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">=></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">'message'</span><span class="p">,</span> <span class="p">(</span><span class="nx">data</span><span class="p">)</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="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">'ERROR'</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">'Rate limit exceeded'</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">'Invalid JSON'</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">'Invalid message format'</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">'/metrics'</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">=></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">'Content-Type'</span><span class="p">,</span> <span class="s1">'text/plain'</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">=></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">'BATCH'</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">'UPDATE'</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">'ws'</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 > 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