Сервер push сообщений
В любом современном интернет сервисе можно выделить всего две основные функции:
- Первая — это авторизация пользователей.
- Вторая — это моментальная отправка некоего события с сервера на клиент.
Первый пункт, думаю, в пояснении не нуждается.
Второй пункт, это клиент серверная технология, но наоборот. Клиент не делает периодически запрос на сервер — есть ли новые сообщения. Сервер, при появлении некоего события, отравляет сообщение сразу клиенту.
Для лучшего понимания сервис не некий сферичный в вакууме. Сервис можно представить как:
- Папка с файлами в облаке. Информация о изменении, добавлении и удалении пересылается другим пользователям или текущему пользователю, но на другие устройства.
- Компьютерная программа чтения логов сервера, при появлении записей «error» отсылающая содержимое записи пользователю на мобильный телефон.
- Видео-глазок (камера), делающий снимки при движении около двери квартиры.
- Сервис получающий телеметрию из приложения android-auto.
- Похожий на предыдущий пункт сервис, позволяющий узнать дошел ли ребенок до школы или пришел из школы домой.
Список можно расширять до бесконечности, приведены, как пример, лишь наиболее известные варианты использования.
Практически все приведенные примеры сервисов можно представить в виде «мессенджера». Часть из примеров именно так и описывалась, видел статьи, как подключить камеру и отправлять снимки в один известный мессенджер.
Не так давно была статья что за сервисом камер в дверных глазках, вместо искуственного интелекта наблюдали посторонние люди. Не буду заострять внимание на бесплатных сервисах от больших «добрых» корпораций. Как говориться в известной пословице «Бесплатный сыр бывает в мышеловке» и руководствуясь другой пословицей «Своя рубашка ближе к телу», свой «сервис» лучше.
Код скриптов сервера открыт и бесплатен
Для реализации выбрал node.js socket.io postgreSQL, первую версию реализовал более двух лет назад, и сервис был тесно связан с 1с https://infostart.ru/public/545047/, они тогда еще нигде не анонсировали сервер взаимодействия. Но это было давно, на данный момент, серверная часть никак не связанна с упомянутой программой, клиентскую часть можно интегрировать в виде внешней обработки или расширения.
Название выбрал многозначительное — «push0k». Первая часть взята от словосочетания «push сообщения», вторая общеизвестное английское окей сокращенно, но пишется через ноль для пущей многозначительности.
В данном случае, это не «бесплатный сыр в мышеловке», так как требуется компьютер windows, linux, macOS (сервер) для работы через интернет, нужен внешний ip адрес, возможно проброшенный. Желательно доменное имя, связанное с внешним ip адресом. Также, желательно, но не обязательно, не само подписанный сертификат связанный с доменным именем.
Требований по железу как таковых нет, может работать и на домашнем nas, где есть docker. Docker в nas означает архитектуру х86-64, и postgreSQL в такой nas без docker не установить. Точное понимание сколько клиентов сможет поддерживать такой сервер, зависит от задач — логики сервиса и передаваемого трафика между клиентами.
Описание сервера:
Сервер использует дополнительные модули:
- socket.io – модуль добавляет websocket протокол с массой доп. возможостей.
- node-postgres – модуль для связи с сервером баз данных postgreSQL.
- pm2 – модуль для запуска нескольких процессов сервера с балансировщиком нагрузки.
Файлы сервера:
- starter.js – http(s) сервис, можно сказать админка сервера. Через этот сервис изменяются настройки и запускаются процессы основного websocket сервера.
- push0k.js — основной websocket сервер.
- starter_cfg.js — настройки административной скрипта сервера. Подключение к postgreSQL и файлы для https подключения. Файлы для https подключения, так и доменное имя, могут отличаться от основного сервера, для большей безопасности. Изменяется вручную, при первом запуске.
- config.js – основные настройки всего сервера.
- package.js – файл описание версия автор необходимые для работы модули.
- push0kStructure.sql – файл описание базы данных postgreSQL для начальной инициализации, пустой базы данных.
Установка:
1. Первоначально необходимо установить node.js nodejs.org/en/download
2. Также должен быть установлен postgreSQL на компьютере локальной сети или том же postgrespro.ru/products/download
На сервере postgreSQL необходимо выполнить файл «push0kStructure.sql» или практически все запросы из этого файла для создания базы данных с необходимыми таблицами.
3. Скачать первые пять файлов сервера, кроме push0kStructure.sql, в любой каталог компьютера.
4. В любом текстовом редакторе отредактировать файл «starter_cfg.js». Важно указать параметры подключения к postgreSQL серверу и установить порт для подключения к административной части сервера push0k.
5. Запустить терминал (консоль) и с помощью команды «cd /путь/вашего/каталога/» перейти в каталог файлов сервера. Указанный в команде терминала путь должен быть из пункта 3.
6. Выполнить команду в терминале «npm install» для установки дополнительных модулей.
Выполнить команду в терминале «node starter.js» для запуска сервиса администрирования.
7. Скачать и установить программу push0k admin. В «push0k admin» настраиваются основные параметры websocket, порт сервера, количество процессов и многие другие. Можно управлять запуском и остановкой процессов сервера, создавать и управлять пользователями и их комнатами(группами).
Приложение push0k admin
Приложение сделано на electron с использованием vue.js. Внутри реализовано подобие оконной системы, небольшие модальные диалоги можно перетаскивать как окна, заголовки окон для windows сделаны аналогично windows 10, для Mac OS как в последних версиях, но пока без учета dark theme. Для linux соберу позднее, там с заголовками диалогов чуть сложнее, думаю будет как в ubuntu и, если не ubuntu, то win 10 style. Потребление памяти в win 10 и Mac OS больше 150 мегабайт не видел.
В предыдущих версиях не было возможности добавить анимацию, сделал немного без фанатизма. Ранее описанные диалоги — окна появляются из центра окна приложения, постепенно увеличиваясь, при закрытии улетают в центр, уменьшаясь. Также анимировано нажатие кнопок и обязательные для заполнения поля.
При реализации было большое желание сделать темную тему, но поскольку еще не было светлой темы, пришлось довольствоваться только панелью кнопок справа. В Mac OS эта единственная темная часть имеет эфект «vibrancy», т. е. частично прозрачна, аналогично большинству окон стандартного интерфейса. К сожалению, в Windows похожий эффект называемый fluent design сделать не получилось т. к. нет в electron подобного функционала для Windows.
Как ранее упоминалось, для управления используются http и ws (websocket) протоколы. Есть возможность использовать защищенные соединения https и wss. При защищенных соединениях можно посмотреть данные используемых сертификатов. Аналогично браузерам используется пиктограмма «Замок» — соединение безопасно, «Открытый замок» — соединение небезопасно. И без пиктограмм, соответственно — защищенное соединение не используется.
Общая логика
Подобного рода приложения никогда не видел. При разработке руководствовался тем, что мне самому было бы интересно мониторить и какие параметры видеть в статистике.
Например, в таблице подключений для каждого подключения есть данные «время подключения», «время авторизации», «время синхронизации». Первое — позволяет понять, как быстро устанавливается соединение «ws://» или защищенное «wss://». Второе — после соединения, отдельно отправляется сообщение с данными авторизации, при авторизации выполняется запрос проверка пользователя и проверка хеша пароля уникального для каждого соединения. Третье — время получения новых сообщений и новых или обновленных справочных данных. Также, сохраняются версии node.js, socket.io, и другие описанные данные в целом позволяют понять, как повлияло обновление node.js или отдельно модуля на скорость, или могла повлиять некая доработка сервера.
В примере выше описана только малая часть таких данных. Также, в отдельной таблице, сохраняется время, размер и скорость мбайт./сек. загрузки данных синхронизации. В той же таблице сохраняются данные загрузки файлов вложений на сервер и скачивание этих данных с сервера.
Время для расчета скорости рассчитывается на клиенте или сервере, зависит от ситуации. Использовать время и сервера и клиента невозможно так как оно не может быть идеально синхронизировано. Это накладывает небольшой лаг размером в величину пинга (подтверждение доставки) между клиентом и сервером. При закачивании или скачивании больших файлов описанный лаг несущественен.
В таблице подключений можно увидеть закрытое соединение с данными «передано байт», «получено байт» и «размер» данных синхронизации больше чем «передано байт». При синхронизации данных используется автоматическое сжатие socket.io, при загрузке или скачивании вложений автоматическое сжатие отключено, так как зачастую сжимать уже сжатое негативно влияет на скорость.
Как написано вначале статьи, никогда не было целью сделать один общий сервис и подключить к нему как можно больше пользователей. Но всегда было интересно, сколько теоретически может быть пользователей и какую нагрузку выдержит сервер.
Для этого сделал простой тест: Онлайн клиентам определенной комнаты (группы), рассылается сообщение с параметрами тестирования (в параметрах всего один основной параметр — количество сообщений), которое каждый клиент пошлет другим клиентам онлайн. После тестовой рассылки подсчитывается общее время всех сообщений, уведомлений, записей в таблицы postgresql, число всех сообщений, уведомлений и записей, и соответственно, рассчитывается скорость, в том числе общая всех операций на сервере.
Пример со скриншота:
Самому порой удивительно, всего 10 000 сообщений и 390 000 телодвижений,
отправка 50 000 сообщений: Процессы сервера: 4 Пользователи: 3
Всего сообщений получено 10 000 * 3 = 30 000
Пересылка в другие процессы сервера 30 000 * Процессы сервера: 4 — 1 = 90 000
Отправлено адресатам 30 000 * Пользователи: 3 — 1 = 60 000
Записано сообщений в таблицу postgreSQL 30 000
Получено уведомлений доставки 90 000
Записано в таблицу postgreSQL уведомлений доставки 90 000
Все операции 390 000
Логика данных в push0k admin
При каждом подключении получаются все справочные данные: пользователи, комнаты, устройства, базы данных, также 300 последних записей «журнально-статистических»: Подключения, Синхронизация данных, Пересылка вложений, Сообщения, Журнал.
Сообщения практически повторяют таблицу postgresql и не имеют фильтров, настроек и формы, где можно увидеть сообщение полностью. Логика таблицы отладочная, возможно быстро посмотреть при разработке, дошло сообщение до таблицы или нет.
Таблицы «Пользователей», «Комнат(групп)», «Подключений» и «Журнал» обновляются автоматически. Для остальных данных нет смысла в онлайн обновлении.
Приложение push0k admin можно загрузить по ссылке:
Windows: push0kadmin Setup 19.1.11.exe
Mac OS: push0kadmin-19.1.11.dmg
Оно бесплатно, но в отличии от сервера, исходный код открывать пока не планирую.
В следующей статье опишу клиентскую часть push0k desctop client, а также небольшой пример, кода и как подключиться, авторизоваться и получить данные с сервера.
Для ранее упомянутых ранних версий был и android клиент, бессмертно живущий в фоне на 7 ой и 8 ой версиях android. Но он пока, думаю не надолго отстал. Позднее, думаю, будет и третья статья с android клиентом, а там глядишь и до iOS недалеко.