RabbitMQ реализует поддержку STOMP через отдельный плагин, который преобразует STOMP-фреймы в внутреннюю модель брокера AMQP. В результате STOMP-клиенты получают доступ к очередям, обменникам и маршрутизации сообщений без прямой работы с AMQP-протоколом.
Ключевая особенность заключается в том, что STOMP выступает как текстовый протокол поверх TCP/WebSocket, а RabbitMQ выполняет роль брокера, обеспечивающего:
При использовании STOMP.js взаимодействие чаще всего происходит через WebSocket-соединение с RabbitMQ STOMP plugin.
Перед установкой соединения необходимо включить поддержку STOMP:
rabbitmq-plugins enable rabbitmq_stomp
rabbitmq-plugins enable rabbitmq_web_stomp
Первый плагин открывает TCP STOMP endpoint, второй — WebSocket-обёртку, необходимую для браузерных клиентов.
После активации становятся доступны порты:
STOMP.js использует WebSocket как транспорт, поверх которого формируется STOMP-сессия.
import { Client } from "@stomp/stompjs";
const client = new Client({
brokerURL: "ws://localhost:15674/ws",
reconnectDelay: 5000,
heartbeatIncoming: 4000,
heartbeatOutgoing: 4000,
});
При использовании RabbitMQ часто применяется логин и пароль:
client.connectHeaders = {
login: "guest",
passcode: "guest",
};
Важно учитывать, что учетная запись guest по умолчанию
ограничена локальным доступом.
После подключения создаётся сессия, в рамках которой доступны подписки и отправка сообщений.
client.onConn ect = () => {
console.log("connected");
};
client.activate();
При установлении соединения RabbitMQ создаёт канал доставки
сообщений, связанный с виртуальным хостом (vhost).
RabbitMQ не использует STOMP-дестинации напрямую. Вместо этого применяется трансляция:
/queue/<queue_name>
Сообщения отправляются в конкретную очередь через default exchange.
client.publish({
destination: "/queue/orders",
body: JSON.stringify({ id: 1, status: "new" }),
});
/topic/<routing_key>
Используется fanout или topic exchange в RabbitMQ.
client.subscribe("/topic/news", (message) => {
const payload = JSON.parse(message.body);
});
В RabbitMQ STOMP может использоваться через привязку routing key:
/exchange/<exchange_name>/<routing_key>
client.publish({
destination: "/exchange/logs/error",
body: "critical error",
});
Подписка создаёт consumer, связанный с очередью или binding’ом exchange.
const subscription = client.subscribe("/queue/tasks", (message) => {
const data = JSON.parse(message.body);
});
Каждое сообщение приходит как STOMP frame, содержащий:
RabbitMQ поддерживает режимы подтверждения:
Сообщение считается доставленным сразу после получения.
client.subscribe("/queue/tasks", handler);
Требуется явное подтверждение:
client.subscribe("/queue/tasks", (message) => {
const data = JSON.parse(message.body);
message.ack();
});
Подтверждение каждого сообщения отдельно:
message.ack({ mode: "client-individual" });
Отсутствие ACK приводит к повторной доставке сообщения.
Отправка формируется через publish:
client.publish({
destination: "/queue/process",
body: JSON.stringify({
task: "resize-image",
payload: {
width: 300,
height: 300,
},
}),
headers: {
persistent: "true",
},
});
persistent — сохранение сообщения на дискpriority — приоритет обработкиexpiration — TTL сообщенияcontent-type — тип данныхRabbitMQ поддерживает время жизни сообщений через заголовок
expiration.
client.publish({
destination: "/queue/cache",
body: "temp data",
headers: {
expiration: "10000",
},
});
Значение указывается в миллисекундах, после чего сообщение удаляется из очереди.
Для устойчивой доставки важно согласование трёх параметров:
STOMP.js не создаёт очередь напрямую — она должна существовать в RabbitMQ заранее или быть создана через административный API.
RabbitMQ и WebSocket-соединения подвержены разрывам. STOMP.js поддерживает автоматическое восстановление:
const client = new Client({
brokerURL: "ws://localhost:15674/ws",
reconnectDelay: 3000,
});
После восстановления соединения подписки могут требовать повторной регистрации, в зависимости от конфигурации STOMP.js.
Heartbeat предотвращает разрыв idle-соединений.
const client = new Client({
heartbeatIncoming: 10000,
heartbeatOutgoing: 10000,
});
RabbitMQ проверяет активность канала и закрывает неактивные соединения.
RabbitMQ использует vhost для изоляции ресурсов.
Подключение через STOMP может включать vhost в URL:
ws://localhost:15674/ws
Или через заголовки:
client.connectHeaders = {
login: "user",
passcode: "pass",
host: "/",
};
Хотя STOMP не управляет QoS напрямую, RabbitMQ применяет prefetch на уровне канала.
При большом потоке сообщений:
RabbitMQ распределяет сообщения между подписчиками:
STOMP.js не контролирует стратегию распределения — она задаётся RabbitMQ.
Типичные сценарии:
Сообщения передаются как текстовые STOMP frames:
SEND
destination:/queue/test
content-type:application/json
{"id":1}
Ответы:
MESSAGE
subscription:sub-0
message-id:123
{"id":1}
В production-средах используется TLS:
wss://broker.example.com:15674/ws
Особенности:
При росте нагрузки учитываются:
STOMP-дестинации транслируются в exchange bindings:
Пример topic routing:
client.subscribe("/topic/orders.*", handler);
Со стороны RabbitMQ:
routing key: orders.created
routing key: orders.deleted
RabbitMQ обеспечивает:
STOMP.js отражает только клиентскую часть этого процесса через ACK/NACK и headers.