Вопрос проверяет понимание механизмов восстановления соединения WebSocket после сбоя, что критично для создания устойчивых real-time приложений.
WebSocket предоставляет полноценное двустороннее соединение, но сетевые проблемы, перезагрузка сервера или простои клиента могут его оборвать. Устойчивое приложение должно автоматически восстанавливать связь.
Клиентская логика отслеживает события WebSocket-объекта. Ключевые события для реконнекта:
onclose: срабатывает при закрытии соединения (нормальном или аварийном).onerror: указывает на ошибку, после которой обычно следует закрытие.При наступлении этих событий запускается процедура повторного подключения.
Простой немедленный повтор может создать нагрузку, если сервер временно недоступен. Распространённая стратегия — экспоненциальная задержка. Интервал между попытками увеличивается по формуле (например, удваивается) до достижения максимума.
let reconnectAttempts = 0;
let maxReconnectDelay = 30000;
function connectWebSocket() {
const ws = new WebSocket('wss://example.com/socket');
ws.onclose = () => {
const delay = Math.min(1000 * Math.pow(2, reconnectAttempts), maxReconnectDelay);
reconnectAttempts++;
setTimeout(connectWebSocket, delay);
};
ws.onopen = () => {
reconnectAttempts = 0; // Сброс счётчика при успешном соединении
};
}
// Первоначальный вызов
connectWebSocket();Иногда соединение формально открыто, но данные не проходят (например, из-за NAT-таймаута). Для обнаружения таких случаев клиент периодически отправляет служебные сообщения (ping), ожидая ответ (pong). Если ответ не пришёл за определённое время, соединение принудительно закрывается, что запускает стандартный реконнект.
// Пример реализации heartbeat на клиенте
let heartbeatInterval;
let pongTimeout;
function setupHeartbeat(ws) {
// Отправляем ping каждые 30 секунд
heartbeatInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({type: 'ping'}));
// Ждём pong 5 секунд
pongTimeout = setTimeout(() => {
console.warn('Pong timeout, closing connection.');
ws.close(); // Это вызовет onclose и реконнект
}, 5000);
}
}, 30000);
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'pong') {
clearTimeout(pongTimeout); // Получили ответ, сбрасываем таймаут
}
};
ws.onclose = () => {
clearInterval(heartbeatInterval);
clearTimeout(pongTimeout);
};
}Автоматический реконнект WebSocket — обязательный элемент для:
Вывод: Реализация реконнекта с экспоненциальной задержкой и heartbeat делает real- time приложение устойчивым к временным сбоям сети и сервера, улучшая пользовательский опыт.
Уровень
Рейтинг:
3
Сложность:
5
Навыки
JavaScript
Networks
Ключевые слова
Подпишись на React Developer в телеграм