Создание клиента

Работа со STOMP.js начинается с создания экземпляра клиента, который управляет жизненным циклом соединения, обменом фреймами и подписками на каналы сообщений. В современной экосистеме чаще используется пакет @stomp/stompjs, предоставляющий класс Client с единым API для WebSocket и SockJS.

Подключение библиотеки

Для установки используется npm-пакет:

npm install @stomp/stompjs

Если требуется поддержка SockJS (например, для обхода ограничений WebSocket), дополнительно устанавливается:

npm install sockjs-client

Импорт в коде:

import { Client } from '@stomp/stompjs';
import SockJS from 'sockjs-client';

Базовое создание клиента

Основная точка входа — объект Client. Он инкапсулирует подключение, отправку сообщений, подписки и обработку событий.

const client = new Client({
  brokerURL: 'ws://localhost:8080/ws'
});

Параметр brokerURL используется при прямом WebSocket-соединении. В этом режиме STOMP-клиент подключается напрямую к серверу брокера.


Использование WebSocket-фабрики

Когда требуется использовать SockJS или кастомную инициализацию WebSocket, применяется webSocketFactory.

const client = new Client({
  webSocketFactory: () => new SockJS('http://localhost:8080/ws')
});

Этот подход позволяет подключаться к серверам, которые не поддерживают нативный WebSocket, но предоставляют HTTP-fallback.


Конфигурация подключения

Клиент STOMP.js поддерживает широкий набор параметров, влияющих на поведение соединения.

Основные параметры

const client = new Client({
  brokerURL: 'ws://localhost:8080/ws',

  connectHeaders: {
    login: 'user',
    passcode: 'password'
  },

  debug: (str) => {
    console.log(str);
  },

  reconnectDelay: 5000,
  heartbeatIncoming: 4000,
  heartbeatOutgoing: 4000
});

Разбор параметров

connectHeaders Передаются в момент CONNECT-фрейма. Используются для авторизации, передачи токенов или метаданных.

debug Функция логирования внутренних событий STOMP-клиента. Позволяет отслеживать фреймы CONNECT, SUBSCRIBE, SEND и DISCONNECT.

reconnectDelay Время в миллисекундах перед автоматической повторной попыткой подключения при разрыве соединения. Значение 0 отключает реконнект.

heartbeatIncoming / heartbeatOutgoing Механизм контроля живости соединения.

  • heartbeatOutgoing — интервал отправки heartbeat-клиентом
  • heartbeatIncoming — ожидаемый интервал heartbeat от сервера

Управление состоянием клиента

После конфигурации клиент необходимо активировать.

client.activate();

Метод activate() инициирует процесс подключения и запускает внутренний цикл управления соединением.

Для корректного завершения используется:

client.deactivate();

Этот вызов закрывает соединение, отменяет подписки и останавливает автоматический реконнект.


Обработка событий подключения

Клиент предоставляет callback-обработчики для ключевых этапов жизненного цикла.

const client = new Client({
  brokerURL: 'ws://localhost:8080/ws',

  onConnect: (frame) => {
    console.log('Подключение установлено');
  },

  onStompError: (frame) => {
    console.error('STOMP ошибка:', frame.headers['message']);
  },

  onWebSocketError: (event) => {
    console.error('WebSocket ошибка', event);
  }
});

onConnect

Вызывается после успешного выполнения STOMP handshake. На этом этапе доступны подписки и отправка сообщений.

onStompError

Срабатывает при ошибках протокольного уровня STOMP, например при отказе брокера или ошибке авторизации.

onWebSocketError

Обрабатывает низкоуровневые ошибки транспорта WebSocket.


Структура клиента внутри

Клиент STOMP.js можно рассматривать как конечный автомат с несколькими состояниями:

  • UNINITIALIZED
  • CONNECTING
  • CONNECTED
  • DISCONNECTING
  • DISCONNECTED

Переходы между состояниями происходят автоматически при вызовах activate() и deactivate(), а также при сетевых сбоях.


Автоматическое переподключение

Механизм реконнекта встроен в Client и активируется при ненулевом reconnectDelay.

reconnectDelay: 3000

При разрыве соединения клиент:

  1. Переходит в состояние DISCONNECTED
  2. Ждёт заданный интервал
  3. Повторяет попытку подключения
  4. Восстанавливает подписки после успешного CONNECT

Подписки при этом обычно нужно восстанавливать вручную, если используется кастомная логика хранения.


Пример полного создания клиента

import { Client } from '@stomp/stompjs';
import SockJS from 'sockjs-client';

const client = new Client({
  webSocketFactory: () => new SockJS('http://localhost:8080/ws'),

  connectHeaders: {
    Authorization: 'Bearer token'
  },

  debug: (msg) => console.log(msg),

  reconnectDelay: 5000,

  heartbeatIncoming: 10000,
  heartbeatOutgoing: 10000,

  onConnect: () => {
    console.log('STOMP подключён');
  },

  onStompError: (frame) => {
    console.error('Ошибка STOMP:', frame.body);
  }
});

client.activate();

Особенности поведения в браузере

В браузерной среде STOMP.js работает поверх WebSocket API, поэтому:

  • соединение подчиняется ограничениям CORS (при SockJS)
  • автоматический reconnect зависит от reconnectDelay
  • heartbeat может быть ограничен прокси или балансировщиками
  • закрытие вкладки приводит к принудительному разрыву соединения

Конфигурация через runtime

Параметры клиента могут быть изменены до вызова activate(). После активации изменение конфигурации не гарантирует применения без пересоздания экземпляра.

client.reconnectDelay = 10000;
client.activate();

Логика безопасной инициализации

Корректная схема создания клиента обычно включает проверку состояния:

if (!client.active) {
  client.activate();
}

Это предотвращает повторные подключения и дублирование соединений.


Работа с несколькими клиентами

STOMP.js допускает создание нескольких независимых клиентов, каждый из которых может работать с разными брокерами или пространствами сообщений.

const chatClient = new Client({ brokerURL: 'ws://localhost:8080/chat' });
const notifClient = new Client({ brokerURL: 'ws://localhost:8080/notify' });

Каждый клиент управляет собственным набором подписок и состоянием соединения, не разделяя внутренние очереди сообщений.