Загрузка…
Загрузка…
Production-клиент WebSocket должен уметь переподключаться с backoff, держать heartbeat и корректно освобождать ресурсы. Без этого соединение «тихо умирает», а после outage все клиенты бьют origin одновременно.
// Production-grade client: reconnect with backoff, heartbeat, and cleanup
function connect() {
const ws = new WebSocket('wss://api.example.com/ws');
let heartbeat;
ws.onopen = () => {
ws.send(JSON.stringify({ type: 'auth', token })); // can't set headers → auth in-band
// Heartbeat: prove the connection is alive; a missing pong means it's dead
heartbeat = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'ping' }));
}, 30_000);
};
ws.onmessage = (e) => handle(JSON.parse(e.data));
ws.onclose = () => {
clearInterval(heartbeat);
// ❌ `setTimeout(connect, 1000)` → every client retries in lockstep = thundering herd
// ✅ exponential backoff + jitter spreads the reconnect storm
const delay = Math.min(1000 * 2 ** attempt, 30_000) * (0.5 + Math.random());
setTimeout(connect, delay);
attempt++;
};
ws.onerror = () => ws.close(); // let onclose own the reconnect logic (one path)
}// Backpressure: don't blindly push — a slow client's buffer will blow up memory
if (ws.bufferedAmount < 1_000_000) ws.send(payload); // else drop/throttle/coalesceВ браузере нельзя задать заголовки при открытии WebSocket — auth идёт in-band в первом сообщении. Heartbeat (ping/pong) — единственный надёжный способ поймать half-open. Экспоненциальный backoff с jitter размазывает reconnect после массового падения. bufferedAmount — защита от переполнения буфера у медленного клиента.
WebSocket-клиент в production: auth in-band, heartbeat, reconnect с jitter и контроль backpressure — без этого real-time быстро ломается под нагрузкой.
