Pull to refresh

Тестирование WebSocket+STOMP соединения через Postman

Level of difficultyMedium
Reading time4 min
Views1.4K

Примечание: в статье описано использование Postman v11.37.5

Оглавление

  1. Вступление

  2. Проблема передачи нулевого байта

  3. Настройка глобальных переменных для тестирования

  4. Создание коллекции WebSocket соединений

  5. Примеры STOMP фреймов

  6. Заключение

Вступление

Всем доброго времени суток! При работе над проектом мне и команде пришлось тестировать передачу сообщений по протоколу STOMP через WebSocket соединение. Обычно для таких задач я использую Postman, который, поддерживает установление WebSocket-соединений, хоть и в beta-версии. Однако я столкнулся с проблемой: согласно спецификации STOMP, в конце каждого фрейма должен находиться нулевой байт (NULL, 00). При этом при отправлении сообщения через Postman нулевой байт не передается корректно. В этой статье я расскажу о причинах этой проблемы и о найденным мной решении.

Проблема передачи нулевого байта

Как оказалось, Postman обрабатывает данные при формировании WebSocket-сообщения как текстовую строку, а не как бинарный массив. Из-за этого нулевой байт (\0) может интерпретироваться как символ окончания строки или игнорироваться вовсе, что приводит к тому, что сервер получает фрейм без обязательного завершающего байта.

При поисках решения я нашел обсуждение на Stack Overflow, где показан рабочий способ тестирования WS+STOMP посредством отправки фреймов в бинарном формате. Хотя это решение работает, постоянная необходимость кодирования сообщений усложняет процесс тестирования. Дополнительные комментарии к этой статье дали понять, как можно добиться добавления нулевого байта в конец фрейма без использования бинарного кодирования, что значительно упрощает задачу.

Настройка глобальных переменных для тестирования

Чтобы обеспечить корректную передачу нулевого байта, необходимо определить глобальную переменную, содержащую этот байт (из практики переменная окружения, не экспортируется при работе с WebSocket-соединеним). Для этого потребуется выполнять скрипты при отправке http запроса (в данный момент Postman не поддерживает выполнение скриптов без запросов).

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

pm.globals.set("NULL_CHAR", '\0')

Http запрос, в котором выполняется данный скрип:

Запрос со скриптом для добавления нулевого байта в глобальную переменную
Запрос со скриптом для добавления нулевого байта в глобальную переменную

Кроме того, для удобства я также настроил переменную для передачи access token. В моём случае это необходимо для корректной передачи токена во фрейме команды CONNECT после установления соединения.

Пример запроса со скриптом на получение токена:

Пример запроса со скриптом на получение токена
Пример запроса со скриптом на получение токена

Пример скрипта для получения токена:

function getToken(callback) {
    const requestOptions = {
        url: '<url>',
        method: 'POST',
        header: {
            'Content-Type': 'application/json'
        },
        body: {
            mode: 'raw',
            raw: JSON.stringify({
                email: "<email>",
                password: "<password>"
            })
        }
    };

    pm.sendRequest(requestOptions, function(err, response) {
        if (err) {
            console.error("Ошибка при получении токена:", err);
            callback(err);
        } else {
            try {
                const jsonData = response.json();
                callback(null, jsonData.access);
            } catch (e) {
                console.error("Ошибка при разборе ответа:", e);
                callback(e);
            }
        }
    });
}

getToken(function(err, token) {
    if (err) {
        console.error("Ошибка при получении токена:", err);
    } else {
        pm.globals.set("ACCESS_TOKEN", token);
        console.log("Новый ACCESS_TOKEN установлен:", token);
    }
});

(Вставьте URL, email и password, если у вас есть возможность получать токен таким образом)

После выполнения скриптов в глобальном окружении Postman должны появиться нужные переменные:

Переменные в глобальном окружении
Переменные в глобальном окружении

Создание коллекции WebSocket соединений

Так как прямое создание коллекции для WebSocket-соединений в Postman пока недоступно, сначала необходимо создать WebSocket-соединение через меню «New». После этого станет возможным создание коллекции, что позволит использовать заранее заготовленные фреймы для отправки сообщений.

  1. Создание соединения:
    Открываем меню «New» и выбираем создание нового WebSocket-соединения.

    Создание WS соединения
    Создание WS соединения
  2. Сохранение эндпоинта:
    Вводим URL для handshake и сохраняем соединение в коллекции.

    Создание WS коллекции
    Создание WS коллекции
  3. Использование сохраненных сообщений:
    После сохранения у нас появляется возможность использовать заготовленные фреймы для тестирования.

    ы

Совет: создавайте дубликаты соединений (Ctrl+D) для тестирования передачи сообщений из одного топика между разными клиентами.

Примеры STOMP фреймов

Пример фрейма CONNECT
Пример фрейма CONNECT

Для корректной обработки сервером все отправляемые STOMP фреймы должны оканчиваться глобальной переменной {{NULL_CHAR}}, которая содержит нулевой байт. Примеры STOMP фреймов:

---Connect--- //фрейм CONNECT с токеном
CONNECT
authorization:Bearer {{ACCESS_TOKEN}}
upgrade:websocket
accept-version:1.2,1.1,1.0
heart-beat:0,0

{{NULL_CHAR}}

---sub-error--- //подписка на топик ошибок
SUBSCRIBE
destination:/user/queue/errors
id:sub_error

{{NULL_CHAR}}

---sub-topic--- //подписка на топик чата
SUBSCRIBE
destination:/topic/messages/
id:sub_1

{{NULL_CHAR}}

---send-topic--- //отправка сообщения в топик чата
SEND
destination:/app/send/
content-type:application/json

{"message": "Test WS connected",}
 
{{NULL_CHAR}}

Заключение

Использование Postman для тестирования WebSocket+STOMP соединений может столкнуться с рядом нюансов, связанных с обработкой нулевого байта в конце фреймов. Несмотря на то, что стандартное поведение Postman не позволяет передавать нулевой байт корректно, существуют способы обойти эту проблему – через настройку глобальных переменных и использование специальных скриптов. Надеюсь, что приведенные примеры и рекомендации помогут вам в тестировании и облегчат работу с WebSocket-соединениями.

Спасибо, что дочитали до конца!

Tags:
Hubs:
+1
Comments0

Articles