UNPKG

solver-sdk

Version:

SDK для интеграции с Code Solver Backend API (совместимо с браузером и Node.js), с поддержкой функциональности мышления (Thinking Mode)

212 lines (162 loc) 9.49 kB
# WebSocket Ping/Pong механизм Данный документ описывает механизм поддержания WebSocket соединений и мониторинга их состояния через ping/pong обмен. ## Обзор функциональности SDK поддерживает автоматический механизм отправки ping-сообщений и обработки pong-ответов для: 1. **Проверки активности соединения** - обнаружение разрывов соединения даже в отсутствие активности 2. **Измерения времени отклика (Round Trip Time, RTT)** - мониторинг качества соединения 3. **Сбора статистики соединения** - для диагностики и отладки 4. **Автоматического обнаружения проблем** - уведомление о потере соединения ## Включение механизма ping/pong ```typescript import { CodeSolverSDK, WebSocketNamespace } from 'solver-sdk'; // Создаем экземпляр SDK const sdk = new CodeSolverSDK({ baseURL: 'https://api.example.com', apiKey: 'your-api-key' }); // Получаем WebSocket клиент const wsClient = sdk.getWebSocketClient(); // Подключаемся к пространствам имен await wsClient.connectToReasoning(); await wsClient.connectToDependencies(); await wsClient.connectToIndexing(); // Включаем автоматический механизм ping/pong // параметры: интервал отправки в мс (по умолчанию 30000) и порог таймаута (по умолчанию 3) wsClient.enablePingPong(10000, 3); // Регистрируем обработчик для события таймаута соединения wsClient.onPingPongEvent('connection_timeout', (data) => { console.log(`Соединение потеряно для namespace ${data.namespace}`); console.log(`Socket ID: ${data.socketId}`); console.log(`Количество пропущенных pong: ${data.timeouts}`); // Здесь можно добавить логику переподключения или уведомления пользователя }); ``` ## Отключение механизма ping/pong ```typescript // Отключение для всех пространств имен wsClient.disablePingPong(); // Отключение для конкретного пространства имен wsClient.disablePingPong(WebSocketNamespace.REASONING); ``` ## Получение статистики ping/pong ```typescript // Получение статистики для всех пространств имен const allStats = wsClient.getPingStats(); console.log('Статистика для всех соединений:', allStats); // Получение статистики для конкретного пространства имен const reasoningStats = wsClient.getPingStats(WebSocketNamespace.REASONING); console.log('Статистика для reasoning:', reasoningStats); // Пример содержимого статистики: // { // namespace: '/reasoning', // socketId: 'socket-id-123', // pingSent: 10, // Количество отправленных ping // pongReceived: 10, // Количество полученных pong // averageRtt: 15.5, // Среднее время отклика (мс) // minRtt: 5, // Минимальное время отклика (мс) // maxRtt: 45, // Максимальное время отклика (мс) // lastRtt: 12, // Последнее измеренное время отклика (мс) // lastPongTimestamp: 1712345678901, // Timestamp последнего полученного pong // isConnected: true // Текущий статус соединения // } ``` ## Ручная отправка ping/pong Хотя SDK обеспечивает автоматический механизм ping/pong, вы также можете вручную отправлять ping-сообщения: ```typescript // Отправка ping и получение pong wsClient.send(WebSocketNamespace.REASONING, 'connection_ping', { timestamp: Date.now() }); // Добавление обработчика для pong-ответов wsClient.on('connection_pong', (data) => { const rtt = Date.now() - data.echo; console.log(`Получен pong, RTT: ${rtt}ms`); }); // Альтернативно, можно использовать готовый обработчик wsClient.on('connection_pong', wsClient.getPongHandler()); ``` ## Обработка отключений и переподключение ```typescript // Обработка события таймаута соединения wsClient.onPingPongEvent('connection_timeout', async (data) => { console.log(`Соединение потеряно для ${data.namespace}`); // Попытка переподключения try { // Отключаемся от проблемного пространства имен wsClient.disconnect(data.namespace); // Пауза перед повторным подключением await new Promise(resolve => setTimeout(resolve, 1000)); // Переподключаемся switch (data.namespace) { case WebSocketNamespace.REASONING: await wsClient.connectToReasoning(); break; case WebSocketNamespace.DEPENDENCIES: await wsClient.connectToDependencies(); break; case WebSocketNamespace.INDEXING: await wsClient.connectToIndexing(); break; } console.log(`Успешно переподключились к ${data.namespace}`); } catch (error) { console.error(`Ошибка при переподключении к ${data.namespace}:`, error); } }); ``` ## Рекомендации по использованию 1. **Интервал ping/pong**: Рекомендуемый интервал - 30 секунд для продакшн и 5-10 секунд для отладки. 2. **Порог таймаута**: Значение 2-3 пропущенных ping/pong позволяет избежать ложных срабатываний при временных задержках сети. 3. **Экономия трафика**: При частой передаче данных через WebSocket можно увеличить интервал ping/pong, так как регулярный обмен данными уже поддерживает соединение активным. 4. **Мониторинг RTT**: Используйте statsPingStats для мониторинга задержек сети и раннего обнаружения проблем с соединением. 5. **Отключение перед закрытием приложения**: Вызывайте disablePingPong() и затем disconnectAll() при закрытии приложения для корректного освобождения ресурсов. ## Пример комплексного использования ```typescript async function setupWebSocketWithHealthMonitoring() { const sdk = new CodeSolverSDK({ baseURL: 'https://api.example.com', apiKey: 'your-api-key', websocket: { reconnect: true, reconnectAttempts: 5, reconnectDelay: 2000 } }); const wsClient = sdk.getWebSocketClient(); // Подключаемся ко всем пространствам имен await wsClient.connectToReasoning(); await wsClient.connectToDependencies(); await wsClient.connectToIndexing(); // Включаем механизм ping/pong для всех соединений wsClient.enablePingPong(20000, 3); // Регистрируем обработчик для события таймаута wsClient.onPingPongEvent('connection_timeout', handleConnectionTimeout); // Периодически проверяем статистику соединений const statsInterval = setInterval(() => { const stats = wsClient.getPingStats(); // Анализируем статистику for (const stat of stats) { if (stat.averageRtt > 500) { console.warn(`Высокая задержка для ${stat.namespace}: ${stat.averageRtt}ms`); } } }, 60000); // Проверка каждую минуту // Функция для обработки таймаута соединения async function handleConnectionTimeout(data) { console.error(`Соединение потеряно для ${data.namespace}`); // Логика переподключения... } // Функция для корректного закрытия соединений function cleanup() { clearInterval(statsInterval); wsClient.disablePingPong(); wsClient.disconnectAll(); } // Возвращаем функцию очистки return cleanup; } // Использование const cleanup = await setupWebSocketWithHealthMonitoring(); // При закрытии приложения window.addEventListener('beforeunload', cleanup); ```