Фрейм STOMP состоит из команды, набора заголовков, пустой строки-разделителя и тела сообщения. Заголовки занимают ключевую роль в протоколе, поскольку именно через них передаётся вся метаинформация: маршрутизация, идентификация подписок, управление подтверждениями доставки и параметры контента.
Каждый заголовок в STOMP представляет собой строку вида:
ключ:значение
Между ключом и двоеточием пробел не является обязательным, но допускается. После двоеточия следует значение, которое интерпретируется как строка.
Набор заголовков располагается последовательно, по одному на строку. Завершение списка заголовков обозначается пустой строкой (LF LF), после которой начинается тело фрейма.
Ключевые свойства:
Заголовки определяют поведение фрейма на всех этапах обработки:
Фактически STOMP рассматривает заголовки как единственный механизм расширения протокола без изменения его базовой структуры.
Разные команды требуют разных наборов заголовков.
Для установления соединения используются заголовки:
Пример:
CONNECT
accept-version:1.2
host:broker.example.com
heart-beat:10000,10000
Отправка сообщения требует указания маршрута:
Пример:
SEND
destination:/queue/orders
content-type:application/json
content-length:45
Подписка на сообщения использует набор управляющих заголовков:
Пример:
SUBSCRIBE
destination:/topic/news
id:sub-001
ack:client-individual
Фреймы доставки сообщений содержат метаданные брокера:
Пример:
MESSAGE
subscription:sub-001
message-id:msg-12345
destination:/topic/news
content-type:application/json
destination является ключевым механизмом маршрутизации.
Он определяет логический адрес доставки сообщения. Формат зависит от брокера, но чаще всего используется URI-подобная структура:
Особенности:
Используется для идентификации подписки или сущности внутри соединения.
Применяется в:
Особенность заключается в том, что id должен быть уникален в рамках одного соединения.
Определяет стратегию подтверждения получения сообщений:
Этот заголовок влияет на надёжность доставки и контроль обработки сообщений на клиенте.
Механизм подтверждения выполнения команд брокером.
Если заголовок receipt присутствует, брокер обязан вернуть фрейм RECEIPT:
receipt:message-xyz
Это используется для операций:
Позволяет отслеживать гарантированное выполнение команды.
Определяет формат тела сообщения:
Влияет на интерпретацию данных получателем, но не на сам протокол.
Указывает точное количество байт тела фрейма.
Критически важен при:
При отсутствии может использоваться разделитель null-байта, но это менее надёжно.
Формат:
heart-beat:cx,cy
Где:
Используется для поддержания соединения и обнаружения разрыва канала.
accept-version:1.0,1.1,1.2
Позволяет согласовать версию протокола между клиентом и брокером.
STOMP накладывает ограничения на допустимые символы в заголовках.
Запрещены:
Для некоторых символов используется экранирование:
Это особенно важно при использовании JSON внутри заголовков или сложных маршрутов.
Протокол допускает повторение одного и того же ключа, однако поведение зависит от реализации брокера:
Поэтому в прикладной разработке рекомендуется избегать повторяющихся ключей.
Заголовки определяют, как интерпретируется тело:
Ошибки в заголовках приводят к:
В STOMP.js заголовки формируются как обычные JavaScript-объекты:
client.publish({
destination: "/queue/orders",
headers: {
"content-type": "application/json",
"receipt": "msg-1"
},
body: JSON.stringify({ id: 10 })
});
При подписке:
client.subscribe("/topic/news", (message) => {
console.log(message.headers);
});
Каждое сообщение в STOMP.js предоставляет доступ к headers как к словарю строк, где значения всегда приходят в виде строкового представления.
Заголовки формируют уровень абстракции над WebSocket, превращая поток байтов в структурированную систему сообщений. Через них реализуются:
Именно за счёт заголовков STOMP остаётся минималистичным, но функционально расширяемым протоколом поверх WebSocket или TCP.