Понадобилось мне тут свести во едино управление счетами и роботами с разных VDS, да так чтобы и интегрировать со свяким было просто, и чтобы работало быстро и надёжно. И конечно доступ из любой точки. Подумал-подумал и решил использовать сервера доставки сообщений, а самые быстрые и простые из них это MQTT. Message Queue Telemetry Transport.
Плюсы выбора:
- протокол стандартизован.
- не накладывает ограничений на передаваемые данные.
- активно используется в IoT, поэтому софта и тулзов к нему море
- очень простой и очень быстрый
- сервера могут образовывать сети и распростаннять сообщения по ним
Более детально про протокол читайте на http://mqtt.org и вообще в гугло-яндексе
Я пока расскажу в трёх словах как всё организуется:
- на VDS-ках ставится локальный сервер (он кстати брокером называется)
- абонируется «центральный» сервер. Можно за деньги, можно бесплатно - на вкус, цвет и возможности. В сети многие предоставляют сервис MQTT
- исключительно админскими методами сервера связываются. То есть надо указать какие данные и куда распространняются
- роботы цепляются к локальным серверам, пишут данные и получают сообщения-команды.
- собственно всё
Основа основ - ставим нужный софт, пишем робота и проверяем работу
Брокер Mosquitto
В первую очередь установим брокер MQTT на рабочую машину.
Возьмём самый лёгкий и простой - mosquitto. Поддерживается правда протокол 3.1, но нам больше пока и не надо.
Проект живёт тут: https://mosquitto.org/ Скачиваем и устанавливаем, не забыв поставить галочку «Service» в инсталляторе. Для удобства стоит добавить в пути (%PATH%) его каталог, по умолчанию С:\Program Files\mosquitto. Виндовс штука оригинальная, поэтому чтобы сервис включился и заработал, компьютер придётся перезагрузить.
Проверяем :
открываем командную строку (cmd), переходим в каталог mosquitto и выполняем :
mosquitto_sub -v -h localhost -t "#"
это мы «подписались» на все сообщения публикуемые на сервере
открываем ещё одну командную строку, тоже переходим к каталог mosquitto и выполняем:
mosquitto_pub -h localhost -t "test" -m "hello word!"
это мы опубликовали сообщение в теме «test»
если опубликованное видно в первом окошке, то и хорошо, у нас всё работает. Если нет, то придётся разбираться..
Итак, у нас теперь есть сервис сообщений через который и будем работать
Клиент mqtt-explorer
Чтобы не всё делать из командной строки, да и вообще для удобства, установим графический клиент MQTT
Скачаем современный графический клиент для mqtt : http://mqtt-explorer.com/
Добавим соединение localhost со стандартным портом, без авторизаций. Соеденимся.
Если ещё не закрыли два окошка cmd от предыдущего шага, то можно вступить с ними в переписку
Пишем код БлджатЪ
А дальше пишем код, который будет использоваться в роботах, чтобы они взаимодействовали с MQTT
Все основные нюансы, которых правда немного, реализованы на «С» в DLL, чтобы на уровне MQL получился максимально удобный для использования интерфейс:
class MQTT; // чтобы не заставлять пользователя порождать ненужные ему классы // позволим ему задавать колбеки :-) // вот такая функция будет вызывать при поступлении сообщений от брокера typedef int (*MQTT_OnMessage)(MQTT *,string topic,uchar &data[],int qos,int retain); // такая при установке соединение typedef int (*MQTT_OnConnect)(MQTT *); // а такая при разрыве typedef int (*MQTT_OnDisconnect)(MQTT *,int); class MQTT { public: // создать подключение к брокеру MQTT(string server="localhost",string persistentDir=""); // задать собственные колбеки для событий int SetCallbacks(MQTT_OnMessage callback,MQTT_OnConnect on_connect,MQTT_OnDisconnect on_disconnect); // подписаться на темы int Subscribe(string topic); // опубликовать сообщение в теме int Publish(string topic,uchar &data[],int data_size,int qos=0,bool retain=false); // (для пущего удобства) опубликовать текстовое сообщение int Publish(string topic,string text,int qos=0,bool retain=false); // время от времени надо запускать Loop int Loop(); ~MQTT(); protected: int id; // рабочий идентификатор bool connected; // признак есть/нет соединение // кол-беки MQTT_OnMessage on_message; MQTT_OnConnect on_connect; MQTT_OnDisconnect on_disconnect; };
И конечно тестово-демонстрационный «эксперт», который будет реализовывать следующее:
- публиковать на сервере поступащие тики
- публиковать текущий бар
- состояние баланса
- позволит передавать на все другие экземпляры сообщение вводимые пользователем
- делать и так-же передавать скриншоты
- реагировать на сообщение «alert» - выбрасывать окошко с текстом
Вот такая вот картинка:
Пользователь вводит текст в поле ввода, нажимает SEND и сообщение рассылается по всем экземплярам. Полученные сообщение просто печатаются в жарнале.
При нажатии sceenshot будет снят скриншот, сохраннён в каталог screenshot и разослан по всем. Принятые скриншоты также будут сохранятся в каталог screenshot
При получении сообщение в теме alert выскочит окошко.
А вот так смотрится это на сервере (посредством mqtt-explorer):
Если я посредством mqtt-explorer опубликую в теме alert «Привет всем !» то на обоих подключенных терминалах выскочат окошки
аналогично можно отправить alert из командной строки или bat файла:
mosquitto_pub -h localhost -t alert -m "Текст алерта"
Весь код mql и созданные dll-ки можно конечно скачать и
использовать mt4mqtt.zip
PS/ в первоначальном архиве, в DLL-ке не было отключено журналирование, она порождала лишний файл с логами. Перекомпилял, без логов - архив перезалил.