Mikrotik, Telegram и не только
Здравствуйте, друзья! Сегодня я хочу рассказать вам, как открыл для себя новый язык программирования, среду исполнения, а ещё готовый фронтенд. И всё это без кучи фреймворков и тысяч библиотек, чистое, непаханое поле…
Однако, давайте по порядку.
Список языков программирования обширен и уже устоялся, по ним много информации и всевозможных курсов. Среды разработки выросли и обзавелись множеством полезных функций, это радует.
Но мне всегда хочется чего-то нового. Долго искать не пришлось, всё уже давно было под рукой. Это Микротик. Вместе с его RouterOS. Как оказалось тут есть практически всё, что нужно и для разработки, и для исполнения кода.
А фронтом стал Телеграм с его bot API. Тут можно создать приятный интерфейс и сделать взаимодействие с ботом, очень похожим на работу с обычной программой. Телеграм мультиплатформенный и с отличным бэк-эндом. Ему бы побольше элементов управления в API и цены б ему не было. Хотя, я уверен он будет развиваться.
Начать стоит с Микротика. Точнее, давайте рассмотрим его скриптовый язык. Он совсем не сложный и на первый взгляд не годится для серьёзной разработки. Но если копнуть глубже, то он раскрывается, хоть и содержит ряд ограничений.
Из самых досадных то, что из числовых имеем только целочисленный тип данных num. Пять разделим на два, получим два. В остальном вполне можно есть.
Я писал на нескольких популярных языках и там много различных структур данных: деревья, списки, мапы. Тут в явном виде ничего этого нет. Из структур есть только массив, правда реализована поддержка многомерных ассоциативных массивов, что позволяет создавать из него нужные структуры.
Рассмотрим наглядно. Обычный одномерный массив – это индексированный список. Элементы можно вставлять в любое место списка.
Одномерный ассоциативный, где элемент key=value, это тоже список, но сортированный по key.
Двумерный – это HashMap. Он же, но ассоциативный – сортированный map.
Из многомерного можно сделать сортированное дерево. Не сортированное тоже можно.
В одном массиве отлично живут и индексированные и именованные элементы. Первые доступны по индексу, вторые по ключу. Так каждый массив может содержать служебную информацию о себе. Например в индексированных элементах хранить имя и размер.
А массив в памяти, т.е. развернутый в глобальную переменную, это доступная для записи и чтения, оперативная память, содержимое которой можно сохранять на диск, если надо. Причем на глобальные переменные ограничений по размеру нет, в отличие от локальных. Ограничивается только оперативной памятью.
Элементом массива может быть даже код. И его можно выполнить, передав туда параметры, не разворачивая в скрипт или функцию, ещё и в отдельном потоке.
Да, многопоточность тоже доступна. Зависит от того, как вызывать код. Есть несколько способов. Из скрипта можем вызвать функцию, развернутую в глобальной переменной, выполнить код из :parse, или вызвать другой скрипт. В этом случае код, который идет ниже места вызова, будет ждать пока отработает его товарищ и только потом продолжит выполняться, если первый чего-нибудь не выкинет.
Всё меняется, если вызывать код командой :execute. Товарищ в этом случае работает сам по себе и ждать его не надо, правда значение не вернет тут же. Всё что ниже такого вызова продолжит выполняться, а результат работы, вызванный выше код, может сохранить в массив или файл.
Код можно запускать как службу. К примеру, в цикле мониторить появление элементов в глобальном массиве и выполнять действия в зависимости от этого. Или проверять наличие сообщений на сервере Телеграм.
Благодаря стараниям уважаемого автора Хабра, Александра @Chupakabra303, Микротик теперь понимает JSON. Автор создал набор библиотек, который парсит JSON объекты в многомерный ассоциативный массив и с ним уже можно работать всеми доступными методами.
Ещё функции… Развернутые в глобальном окружении, они постоянно доступны в памяти. В любой момент можем вызвать их из кода или консоли, передав туда параметры, как именованные, так и по индексу. Об этом подробнее можно почитать у местных уважаемых авторов, здесь и здесь.
Есть проверка синтаксиса. Можно вывести в консоль содержимое скрипта командой [/system script print from=script] и в месте, где есть ошибка шрифт станет монохромным. Если ошибок нет, то будет разноцветным, как новогодняя ёлка.
Отладка реализуется выводом в лог или консоль значения любой переменной. Что ещё нужно?
Ах, да. Нужна нормальная среда разработки. Таких много. Для себя выбрал редактор Atom от команды GitHub. У него есть много плагинов, в том числе RouterOS plugin. Плюс нативная поддержка контроля версий Git. Работать вполне комфортно.
Всё это в совокупности позволяет создать на базе RouterOS полноценный бэк-энд для мобильных приложений. Для Телеграм вообще подходит идеально.
Многие правильно подметят, а как же базы данных? Где данные хранить, запросы куда отправлять?
Это тоже решаемо. Есть СУБД как SQL, так и noSQL, которые поддерживают HTTP(S) API и JSON. Для управления временными рядами есть InfluxData, которая из коробки работает с https и JSON. Она подходит для мониторинга параметров самого устройства, а также для сбора всевозможных метрик с фронта. Дружит с Grafana, есть дашборды и всё красиво.
А можно использовать массивы. И даже создать СУБД на их основе, с запросами и прочим. Когда будет время займусь этим плотнее.
И все это не только для управления параметрами маршрутизатора. Ничего не мешает обрабатывать данные других сервисов с JSON сериализацией и возвращать результат. Если развернуть RouterOS в виртуальной среде, то можно оперировать ресурсами. Захостить её в облаке не проблема.
Пока это только теория. А как на практике? Покажу на примере Телеграм бота, который разработан с использованием почти всех, описанных выше, возможностей. Здесь кода не будет. Скорее демонстрация работы связки Микротик плюс Телеграм. Архитектура приложения, интерфейс, bot API и немного о безопасности.
Начнем с архитектуры. Мне понравилась статья одного из авторов Хабра "Создание архитектуры программы или как проектировать табуретку".
Приведу небольшую выдержку из нее.
С этим трудно не согласиться. Монолитный код замучаешься читать, об отладке и поддержке вообще молчу. Поэтому - модульность. В RouterOS реализуется с помощью функций. В боте их условно можно разделить на несколько типов.
Библиотечные. Часто используются другими модулями и реализуют работу с API Телеграм например. Отвечают за отправку сообщений или построение кнопок и клавиатур.
Функции создания пользовательских интерфейсов. Они "рисуют окна" исходя из назначения и переданных параметров.
Функции обработчики. Эти содержат логику и обрабатывают команды, полученные от клиента. Для каждого модуля свой обработчик.
И функции диспетчеры, которые определяют какому модулю предназначена команда и передают ему управление. Таких в программе три. Первый обрабатывает Callbackи - это нажатие на кнопку, второй текстовые команды и третий команды модуля Терминала.
Код, который отслеживает наличие сообщений, работает как служба. Никаких шедулеров, он постоянно в работе. В бесконечном цикле мониторит сервер Телеграм, получает сообщения и, в зависимости от типа, передаёт их функции диспетчеру, предварительно проверив права пользователя на работу с системой в целом.
Процессор такой подход совсем не нагружает, зато повышает скорость обработки сообщений.
Конечно все паттерны тут не реализуешь, но...
Теперь про интерфейс. Я видел много Телеграм-ботов и большинство из них не заботятся о чистоте пользовательского пространства. Каждое новое действие там - это новое сообщение, что для работы совсем не удобно. Такое ощущение, что их разработчики просто ленятся сделать красиво. А ведь в Телеграм есть функции для редактирования messageй. Можно отдельно редактировать и сам текст и клавиатуру под ним. Конечно не все этим грешат но, повторюсь, большинство не заморачивается.
Чтобы не дублировать код в модулях, были написаны библиотечные функции для работы с bot API. Их я выложил на русскоязычном форуме Микротик, кому надо можете пользоваться. Там есть всё, чтобы создать и отправить сообщение с текстом, фото, клавиатурой и т.д. Для редактирования и удаления тоже есть.
Настройки самого бота хранятся в массиве и считываются оттуда по необходимости.
Безопасность обеспечивается управлением пользовательскими разрешениями. Они тоже хранятся в массиве. Проверяются в функции обработчике перед выполнением команды.
Базовая версия бота опубликована на моем Телеграм канале. Написана так, что позволяет использовать его, как основу для разработки и подключения своих модулей. Используя эти наработки, любой из вас может самостоятельно дописывать нужный функционал.
Резюмируя можно сказать, что RouterOS, на мой взгляд, является неплохой средой разработки и исполнения. Конечно со своими тараканами, но их не так много. Я уверен, что рано или поздно её "распробуют" и другие разработчики приложений.Как оказалось Микротик подходит для разработки Телеграм ботов, вообще не связанных с управлением самим устройством. Чтобы подтвердить этот тезис, я начал работу над новым проектом. Это будет сервис, связанный с геопозиционированием. Тут будет задействован и inline режим. Сейчас о подробностях говорить рано, но прототип уже есть, он работает и пока непреодолимых препятствий я не вижу.
Конечно много чего ещё хочется написать, но тогда статья слишком распухнет. И так занял много вашего времени.
Спасибо, что дочитали до конца. Сильно не пинайте.
p.s. Проект ищет инвестора. Если кому-то станет интересно - пишите на почту [email protected]