В STOMP-протоколе сообщение состоит из заголовков и тела. Если заголовки определяют метаданные доставки и обработки, то тело сообщения (message body) содержит полезную нагрузку, передаваемую между клиентом и брокером. В STOMP.js работа с телом сообщения напрямую связана с тем, как данные сериализуются, интерпретируются и декодируются на разных сторонах WebSocket-соединения.
Тело сообщения в STOMP представляет собой непрозрачный байтовый блок, который следует сразу после заголовков и отделяется символом пустой строки. Протокол не накладывает строгих ограничений на формат данных внутри тела, оставляя это на усмотрение разработчика и серверной реализации.
Ключевая особенность:
В STOMP.js тело сообщения обычно передаётся как строка или бинарный буфер.
Наиболее распространённый сценарий использования STOMP.js — передача текстовых сообщений. В этом случае тело сообщения представлено строкой, чаще всего в формате JSON.
Пример отправки:
client.publish({
destination: "/app/chat",
body: JSON.stringify({
user: "alex",
message: "Привет"
})
});
В данном случае:
При получении:
client.subscribe("/topic/chat", (message) => {
const payload = JSON.parse(message.body);
console.log(payload.user, payload.message);
});
message.body всегда приходит как строка, если не
используется бинарный режим.
STOMP предполагает использование UTF-8 для текстовых сообщений. Это означает, что:
На практике STOMP.js скрывает детали кодировки, но разработчик должен учитывать их при работе с бинарными данными или межъязыковыми системами.
Хотя STOMP-протокол не навязывает строгую семантику
content-type, многие брокеры и серверные реализации
используют этот заголовок для определения способа обработки тела
сообщения.
Пример:
client.publish({
destination: "/app/data",
body: JSON.stringify({ id: 1 }),
headers: {
"content-type": "application/json"
}
});
Типичные значения:
text/plain — простой текст;application/json — JSON-структуры;application/octet-stream — бинарные данные.Важно, что STOMP.js сам по себе не парсит тело на основе
content-type, но сервер может использовать этот заголовок
для десериализации.
При подписке на destination STOMP.js предоставляет объект сообщения,
содержащий поле body.
client.subscribe("/topic/updates", (message) => {
console.log(message.body);
});
Особенности:
body всегда строка (в текстовом режиме);message.headers.Пример работы с заголовками и телом:
client.subscribe("/topic/events", (message) => {
const type = message.headers["event-type"];
const data = JSON.parse(message.body);
if (type === "user_join") {
console.log("Пользователь подключился:", data.name);
}
});
STOMP допускает сообщения без тела. В этом случае:
body может быть пустой строкой;Пример:
client.publish({
destination: "/app/ping",
body: ""
});
Использование пустого тела характерно для:
STOMP.js поддерживает передачу бинарных данных, но поведение зависит от транспорта (WebSocket) и версии реализации.
При работе с бинарными payload используются Uint8Array
или ArrayBuffer.
Пример отправки бинарных данных:
const bytes = new Uint8Array([1, 2, 3, 4]);
client.publish({
destination: "/app/binary",
binaryBody: bytes
});
При получении:
client.subscribe("/topic/binary", (message) => {
const bytes = message.binaryBody;
console.log(bytes);
});
Особенности бинарного режима:
body заменяется на binaryBody;Размер тела сообщения ограничивается не STOMP.js, а:
Типичные проблемы при больших payload:
Практика показывает, что большие данные лучше:
Наиболее распространённый формат тела в STOMP.js — JSON. Это связано с тем, что:
Типичный паттерн:
const payload = {
type: "message",
timestamp: Date.now(),
data: {
text: "Hello"
}
};
client.publish({
destination: "/app/events",
body: JSON.stringify(payload),
headers: {
"content-type": "application/json"
}
});
На стороне клиента:
client.subscribe("/topic/events", (message) => {
const event = JSON.parse(message.body);
handleEvent(event);
});
Так как STOMP.js не выполняет автоматический парсинг, ошибки обработки тела сообщения ложатся на прикладной уровень.
Типичные проблемы:
Защищённая обработка:
client.subscribe("/topic/data", (message) => {
try {
const data = JSON.parse(message.body);
process(data);
} catch (e) {
console.error("Ошибка парсинга сообщения", e);
}
});
Тело сообщения тесно связано с заголовками, которые определяют контекст интерпретации.
Примеры взаимодействия:
content-type определяет формат тела;content-length может указывать размер;Пример:
client.publish({
destination: "/app/upload",
body: fileData,
headers: {
"content-type": "application/octet-stream",
"file-name": "image.png",
"content-length": fileData.length
}
});
STOMP не является потоковым протоколом в классическом смысле, но тело сообщения может использоваться для имитации потоков:
Пример:
client.publish({
destination: "/app/chunk",
body: JSON.stringify({
id: "file1",
index: 1,
total: 10,
chunk: "base64data..."
})
});
На стороне обработки:
id;index;total.Поведение тела сообщения может отличаться в зависимости от брокера:
Несмотря на это, STOMP.js остаётся нейтральным слоем, который: