Отправка текстовых данных в STOMP.js выполняется через метод
publish(). Этот метод формирует STOMP-фрейм
SEND и передаёт его брокеру сообщений.
Базовый пример:
client.publish({
destination: '/topic/chat',
body: 'Привет, сервер!'
});
После вызова библиотека формирует примерно такой STOMP-фрейм:
SEND
destination:/topic/chat
content-length:16
Привет, сервер!
Ключевым параметром является destination — адрес
назначения сообщения. Именно туда брокер направляет переданные
данные.
Метод publish() принимает объект с параметрами.
Стандартная структура:
client.publish({
destination: '/topic/messages',
headers: {},
body: '',
binaryBody: null,
skipContentLengthHeader: false
});
На практике чаще всего используются только:
client.publish({
destination: '/topic/messages',
body: 'Текст сообщения'
});
destinationПоле destination определяет канал, очередь или маршрут
доставки.
Примеры:
destination: '/topic/news'
destination: '/queue/tasks'
destination: '/app/chat'
Назначение зависит от конфигурации брокера:
| Префикс | Назначение |
|---|---|
/topic/ |
Публикация в топик |
/queue/ |
Очередь сообщений |
/app/ |
Маршрутизация на серверное приложение |
/exchange/ |
RabbitMQ exchange |
/user/ |
Персональные сообщения |
Текст сообщения передаётся через поле body.
Пример:
client.publish({
destination: '/topic/chat',
body: 'Новое сообщение'
});
STOMP.js автоматически преобразует строку в текстовый payload.
STOMP поддерживает многострочные сообщения без дополнительных настроек.
Пример:
client.publish({
destination: '/topic/logs',
body: `
Ошибка подключения
Повторная попытка
Соединение восстановлено
`
});
Получатель получит полный текст вместе с переводами строк.
Шаблонные строки позволяют удобно формировать сообщения.
const user = 'admin';
const action = 'login';
client.publish({
destination: '/topic/activity',
body: `${user} выполнил действие: ${action}`
});
Наиболее распространённый сценарий — сериализация объекта в JSON.
const message = {
id: 15,
text: 'Привет',
author: 'Alex'
};
client.publish({
destination: '/topic/chat',
body: JSON.stringify(message)
});
Получение:
client.subscribe('/topic/chat', message => {
const data = JSON.parse(message.body);
console.log(data.text);
});
Для логирования или отладки иногда используют форматированный JSON.
client.publish({
destination: '/topic/debug',
body: JSON.stringify(data, null, 2)
});
Такой вариант увеличивает размер сообщения, но делает содержимое читаемым.
STOMP.js часто используется для передачи команд.
Пример:
client.publish({
destination: '/app/commands',
body: 'RESTART_SERVER'
});
Или:
client.publish({
destination: '/app/commands',
body: 'CLEAR_CACHE'
});
STOMP позволяет прикреплять метаданные через
headers.
Пример:
client.publish({
destination: '/topic/chat',
headers: {
priority: 'high',
sender: 'frontend'
},
body: 'Системное уведомление'
});
Получение заголовков:
client.subscribe('/topic/chat', message => {
console.log(message.headers.priority);
console.log(message.headers.sender);
});
content-typeПри отправке текстовых данных полезно явно указывать MIME-тип.
Пример:
client.publish({
destination: '/topic/json',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
event: 'login'
})
});
Для обычного текста:
headers: {
'content-type': 'text/plain'
}
Для HTML:
headers: {
'content-type': 'text/html'
}
content-lengthSTOMP.js автоматически рассчитывает длину сообщения.
Пример:
client.publish({
destination: '/topic/test',
body: 'Hello'
});
Библиотека сама добавит:
content-length:5
content-lengthНекоторые брокеры работают без заголовка длины.
Для этого используется:
client.publish({
destination: '/topic/test',
body: 'Hello',
skipContentLengthHeader: true
});
Отправка без активного подключения вызывает ошибку.
Безопасный вариант:
if (client.connected) {
client.publish({
destination: '/topic/chat',
body: 'Сообщение'
});
}
Частая ошибка — попытка публикации до завершения соединения.
Неправильно:
client.activate();
client.publish({
destination: '/topic/chat',
body: 'Текст'
});
Правильно:
client.onConn ect = () => {
client.publish({
destination: '/topic/chat',
body: 'Текст'
});
};
client.activate();
Пример пакетной публикации:
for (let i = 1; i <= 5; i++) {
client.publish({
destination: '/topic/counter',
body: `Сообщение ${i}`
});
}
setInterval(() => {
client.publish({
destination: '/topic/time',
body: new Date().toISOString()
});
}, 1000);
const formData = {
login: 'admin',
password: '123456'
};
client.publish({
destination: '/app/auth',
body: JSON.stringify(formData)
});
button.addEventListener('click', () => {
client.publish({
destination: '/topic/actions',
body: 'button_click'
});
});
sendButton.addEventListener('click', () => {
const text = input.value;
client.publish({
destination: '/app/chat',
body: JSON.stringify({
text: text,
date: Date.now()
})
});
input.value = '';
});
STOMP допускает пустое тело сообщения.
client.publish({
destination: '/topic/ping',
body: ''
});
Иногда такие сообщения используются как сигналы или heartbeat-пакеты.
STOMP.js корректно работает с UTF-8.
Пример:
client.publish({
destination: '/topic/chat',
body: 'Привет 世界 ?'
});
Тело сообщения не требует ручного экранирования.
client.publish({
destination: '/topic/test',
body: 'Строка с : двоеточием и\nпереносом'
});
STOMP.js самостоятельно обработает передачу данных.
Максимальный размер зависит от брокера.
Например:
Очень большие текстовые payload могут:
Пример:
const largeText = 'A'.repeat(500000);
client.publish({
destination: '/topic/big',
body: largeText
});
При работе с крупными сообщениями желательно:
Для диагностики удобно включать debug-режим.
client.debug = message => {
console.log(message);
};
После этого STOMP.js начнёт выводить информацию о фреймах:
>>> SEND
destination:/topic/chat
content-length:5
Ошибки могут возникать при:
Пример обработки:
try {
client.publish({
destination: '/topic/chat',
body: 'Hello'
});
} catch (error) {
console.error(error);
}
STOMP поддерживает транзакционные публикации.
Создание транзакции:
const tx = client.begin();
Отправка:
client.publish({
destination: '/queue/tasks',
body: 'Task 1',
headers: {
transaction: tx.id
}
});
Подтверждение:
tx.commit();
Отмена:
tx.abort();
async function sendMessage() {
const response = await fetch('/api/message');
const text = await response.text();
client.publish({
destination: '/topic/server',
body: text
});
}
Во время потери соединения сообщения могут теряться.
Пример очереди повторной отправки:
const pendingMessages = [];
function send(text) {
if (client.connected) {
client.publish({
destination: '/topic/chat',
body: text
});
} else {
pendingMessages.push(text);
}
}
client.onConn ect = () => {
while (pendingMessages.length > 0) {
const text = pendingMessages.shift();
client.publish({
destination: '/topic/chat',
body: text
});
}
};
Сам метод publish() не гарантирует доставку
сообщения.
Гарантия зависит от:
Для критически важных данных обычно используют:
import { Client } from '@stomp/stompjs';
const client = new Client({
brokerURL: 'ws://localhost:15674/ws'
});
client.onConn ect = () => {
client.subscribe('/topic/chat', message => {
console.log('Новое сообщение:', message.body);
});
document
.getElementById('send')
.addEventListener('click', () => {
const input = document.getElementById('message');
client.publish({
destination: '/topic/chat',
body: input.value
});
input.value = '';
});
};
client.activate();
client.publish(...)
до onConnect.
destination: 'chat'
Вместо:
destination: '/topic/chat'
Неправильно:
body: {
text: 'Hello'
}
Правильно:
body: JSON.stringify({
text: 'Hello'
})
JSON.parse(message.body)
при получении обычного текста.
body: hugeData
может привести к закрытию соединения брокером.
Для текстовых сообщений обычно используют:
| Тип данных | Формат |
|---|---|
| Простые команды | String |
| Структурированные данные | JSON |
| Логи | Plain Text |
| События | JSON |
| Уведомления | String / JSON |
Практически все современные STOMP-приложения используют JSON как основной формат обмена данными благодаря: