Методы отладки приложений на socket.io

Методы отладки приложений на socket.io

Socket.io — популярная библиотека для организации передачи данных от браузера серверу и наоборот. Использовать ее достаточно просто, но на больших проектах возникает проблема отладки как сервера, так и клиента.

Предположим мы делаем чат, в котором пользователи общаются между собой. Приложение состоит из браузерного клиента и сервера на node.js. Если приложение делает один человек, то проблем с отладкой скорее всего не возникнет: он откроет Chrome Web Tools и посмотрит, что и куда запрашивается. Но когда клиент и сервер делают разные люди, может получиться, что сервер уже готов, а клиент еще нет или наоборот.

Со стороны сервера у нас имеется 3 cобытия:

  • register
  • login
  • message
  1. register, передаем login и password . Данные передаются первым аргументом в объекте: < login: ‘pavel’, password: ‘1234’ >. Вторым аргументом идет callback, который получит ошибку, если она есть. Callback соответствует принятому в node.js - первый параметр - ошибка, если есть, второй - ответ.
  2. login, данные те же, что и у register. В callback передается accessToken , если ошибок нет.
  3. message - < token: '', message: ' < text >'>

Отвечать на пришедшее сообщение необязательно отправкой другого сообщения, можно передать последним аргументом callback и просто вызывать его как обычный callback в любой другой ситуации. Подробнее об этом.

Входящее событие message содержит данные вида

Рассмотрим, как отладить сервер, если у нас ещё не готов клиент.

Встроенные логи socket.io

Сама библиотека предоставляет некоторые возможности для отладки. Включить их можно с помощью localStorage.debug='*' в браузере или запуская сервер с переменной окружения DEBUG=* . Используется библиотека debug, предоставляющая удобные логи, которые можно гибко настраивать, указывая параметры вместо * в выражениях выше.

В нашем случае такой способ сам по себе мы использовать не можем, поскольку нужен клиент, но его можно применять в совокупности с другими методами.

Во всех последующих примерах предполагается что сервер уже запущен с логированием, его адрес http://localhost:8888/.

Chrome Dev Tools

В первом методе предполагается написание нужного для проверки кода прямо в консоли браузера, со всеми подключениями к сокету, навешиванием событий и т.п.

Попробуем отправить сообщение, используя такой метод. Для начала нужно найти страницу, где уже подключена библиотека socket.io, либо написать свою. Как вариант, зайти на сайт http://socket.io/.

Открываем консоль, создаем соединение:

В консоли сервера видим, что подключение состоялось:

Теперь можем регистрироваться, логиниться и пробовать отправить что-нибудь:

Сразу становится очевиден минус такого подхода: приходится писать все в одну строку, что катастрофически сказывается на читабельности. Допустим ошибок не возникло, тогда в переменной window.token будет токен юзера, который нужен для отправки сообщений.

В консоли сервера видим, что сообщения пришли:

И на login пришел ответ:

Теперь подпишемся на событие message , чтобы получить сообщение:

Логика отправки сообщений проста — при получении события, сервер проверяет правильность токена, и если все хорошо, пересылает сообщение всем подключенным клиентам, включая того, кто его отправил. Может быть это не самое удачное решение, но для демонстрации сгодится.

Отправляем само сообщение:

Сообщение пришло, сервер подставил имя автора дополнительно к тексту:

Таким нехитрым образом можно проверять простую логику или наличие соединения. Но что-то более сложное сделать проблематично — приходится все записывать в одну строку, либо использовать Shift+Enter в консоли, чтобы сделать переход на новую, но об этом легко забыть и выполнить еще недописанный код.

Отдельная HTML-страничка

Логичным продолжением написания кода в консоли будет вынесение его в отдельный файл. Это избавляет от необходимости каждый раз переписывать все команды заново, достаточно перезагрузить страницу. Результат работы можно выводить в ту же консоль, отображать в HTML, в крайнем случае показывать alert-ами.

Делать мы будем то же самое, что и в прошлом примере. В итоге получим макет клиента. Для более сложных приложений можно разбить отдельные части по разным файлам, например отдельно авторизация, отдельно чат, отдельно звонки и т.п.

Внешне клиент выглядит примерно следующим образом:

Здесь есть необходимые формы, а также поля с отладочной информацией. Ознакомиться с кодом можно тут.

По сравнению с предыдущим вариантом добавилась обработка ошибок и интерфейс. При этом мы можем все так же открыть консоль и выполнить некоторый код там, если нам нужна интерактивность. Но отдельный файл можно поместить в репозиторий и им например могут воспользоваться тестировщики. Часто таким образом делают всевозможные генераторы. Допустим нам нужно иметь в системе 100 пользователей. Их, конечно же, можно зарегистрировать вручную, но это займет уйму времени. А если их надо не 100, а 1000? Или 10000? Тут на помощь приходит генератор. Для нашего случая создаем форму с параметрами: количество пользователей и пароль. И регистрируем пользователей:

Автоматизированные тесты

Улучшением предыдущего метода является написание тестов. В отличии от него, тесты могут (и должны) быть выполнены автоматически. Для node.js существует socket.io клиент, установим его:

Установим нужные зависимости для тестов:

Создаем файл теста, подключаем необходимые модули:

Пишем пару тестов для примера. В реальном приложении их может быть значительно больше.

Полностью файл теста располагается тут. Для удобства, допишем в package.json команду тестирования:

Запускаем: npm test

Если сервер запущен, то в консоли мы увидим:

Тесты прошли успешно. Далее можно добавлять еще тестов, проверить на возникающие ошибки, например.

Недостаток такого метода — нужно писать код тестов, расставлять проверки, но это компенсируется удобством дальнейшего использования. Также проблему представляет база данных. В более-менее сложном приложении без нее не обойтись, и для тестирования она нужна отдельная.

Специальное приложение или веб-сайт

Часто возникает ситуация, когда нужно не комплексное тестирование, а отладка в реальном времени, интерактивно. В таком случае методы 2 и 3 нам категорически не подходят, поскольку в них нужно учесть возможные ситуации заранее. Первый способ лучше в этом плане, но далек от идеала из-за необходимости писать много лишнего кода. Специальное приложение позволяет решить эту проблему — нам вообще не нужно писать код, мы отправили событие, посмотрели ответ, решили что делать, отправили второе событие и т.д. Тут клиентом выступаем мы сами, но нам нужен удобный транспорт для передачи событий.

Таких приложений не так уж и много и они не блещут функциональностью:

    • Возможно подключение к нескольким серверам одновременно
    • Чтобы получать сообщения, на событие нужно подписаться
    • Отправка только простых текстовых данных
    • Возможна отправка объектов, формат YAML
    • Не запоминает последние введенные данные

    Как средство тестирования приложение — не лучший выбор, нужно постоянно помнить алгоритм, и не ошибаться при вводе. Оно больше подходит разработчику клиента, чтобы изучить API, посмотреть что откуда возвращается, какие приходят события и т.п.

    Выводы

    Каждый метод хорош по-своему, никто не запрещает использовать все, либо какие-то комбинации из них. Если нужно регулярное тестирование — на помощь придут автоматизированные тесты. Необходима интерактивность — используем приложение. Нужно сгенерировать что-то — больше всего подойдет специально созданная HTML-страница.