Подключение STOMP-клиента к брокеру сообщений является многоэтапным процессом, зависящим от транспортного уровня (WebSocket или SockJS), конфигурации брокера, сетевых условий и корректности параметров клиента. Ошибки могут возникать как на этапе установления соединения, так и после его успешного создания.
На уровне STOMP.js подключение обычно инициируется через
Client.activate(), после чего библиотека пытается
установить транспортное соединение и выполнить STOMP handshake. Любое
отклонение на этом пути приводит к переходу клиента в состояние ошибки
или повторного подключения.
Ключевые источники проблем:
STOMP.js управляет состоянием соединения через внутреннюю машину состояний. Ошибка может возникнуть на разных этапах:
Каждый этап генерирует разные типы ошибок, которые отражаются через
callbacks onStompError, onWebSocketError, а
также события onDisconnect.
WebSocket-ошибки возникают до того, как STOMP-протокол начинает обмен кадрами. Они связаны с транспортом и сетевым уровнем.
Типичные сценарии:
STOMP.js обрабатывает такие ситуации через событие:
client.onWebSocketEr ror = (event) => {
console.error('WebSocket error', event);
};
Важно учитывать, что WebSocket-ошибка не содержит STOMP-контекста, так как STOMP-сессия ещё не установлена.
После установления WebSocket соединения клиент отправляет STOMP frame
CONNECT. На этом этапе возможны логические ошибки
протокола.
Основные причины:
login / passcodeПример обработки:
client.onStompEr ror = (frame) => {
console.error('Broker error:', frame.headers['message']);
console.error('Details:', frame.body);
};
STOMP ERROR frame содержит:
message — краткое описаниеversion — версия протокола (иногда)body — расширенная информация от брокераМногие брокеры (RabbitMQ, ActiveMQ, Spring STOMP endpoints) требуют авторизацию на этапе CONNECT.
Ошибки проявляются как:
Типичная проблема — передача заголовков в неправильном формате:
client.connectHeaders = {
login: 'user',
passcode: 'password'
};
Некоторые серверы требуют кастомные headers:
AuthorizationПри их отсутствии соединение может быть формально установлено на уровне WebSocket, но STOMP-сессия будет немедленно разорвана.
При использовании SockJS транспорт проходит через HTTP fallback механизмы. В этом случае добавляется слой браузерной политики CORS.
Основные проблемы:
Access-Control-Allow-OriginSockJS может маскировать ошибку как “transport failure”, хотя первопричина находится на уровне HTTP.
STOMP.js поддерживает автоматический механизм переподключения через
reconnectDelay. Ошибки соединения не всегда являются
критическими и могут быть временными.
const client = new Client({
brokerURL: 'wss://example.com/ws',
reconnectDelay: 5000
});
Поведение при ошибках:
Контроль состояния осуществляется через:
onWebSocketCloseonDisconnectЗакрытие WebSocket может происходить как инициировано сервером, так и клиентом. Коды закрытия помогают определить причину:
STOMP.js не всегда раскрывает код напрямую, поэтому диагностика часто требует логирования уровня транспорта.
Эффективная обработка ошибок невозможна без детального логирования всех этапов подключения.
Рекомендуемая стратегия:
open,
error, close)Пример расширенного логирования:
client.debug = (str) => {
console.log('[STOMP]', str);
};
При необходимости анализа сетевых проблем полезно включать DevTools Network WebSocket inspection для просмотра frame-level обмена.
Внутреннее состояние Client изменяется в зависимости от
типа ошибки:
CONNECTING — попытка установления соединенияCONNECTED — успешное подключениеRECONNECTING — попытка восстановленияDISCONNECTED — завершённое состояниеCLOSING — инициировано закрытиеОшибки могут переводить клиент в разные состояния без явного уведомления через API, если не реализованы обработчики событий.
Spring WebSocket STOMP endpoints:
/ws endpoint конфигурацииRabbitMQ STOMP plugin:
Heartbeat механизм влияет на устойчивость соединения. При его некорректной настройке возможны скрытые разрывы.
Сценарии:
Heartbeat ошибки часто интерпретируются как сетевые сбои, хотя являются логической ошибкой конфигурации.
Отсутствие ответа от сервера в разумный промежуток времени приводит к таймауту транспортного уровня.
Причины:
STOMP.js не всегда предоставляет отдельное событие таймаута, поэтому оно проявляется как WebSocket close без error frame.
Устойчивость к ошибкам достигается комбинацией нескольких механизмов:
Поведение клиента при нестабильной сети определяется не только библиотекой, но и архитектурой приложения, в котором она используется.