4 место Автоматизируем WebSocket

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Всем привет. В прошлом по теме WebSocket уже была представлена информация с рабочими решениями. В данной статье моей целью является освежить общее представление о WebSocket, а так же создать более универсальное решение, которое можно было бы применить для как можно более широкого спектра сервисов. Так как одна из актуальных тем это криптовалюта, то пример будет на основе работы с одной из крипто-бирж. Статья адресована от среднего уровня и ниже, т.к. продвинутым пользователям не составит труда запилить WebSocket под свои конкретные нужды, а для новичков это скорее всего тёмный лес, с учётом того, что ZennoPoster из коробки не имеет специальных кубиков для таких задач.

Немного теории.

Протокол WebSocket позволяет обмениваться данными между браузером и сервером в реальном времени используя постоянное соединение. Эти данные представляют собой так называемые "пакеты" и передаются в обоих направлениях без разрыва соединения и каких-либо дополнительных HTTP-запросов.
Если сравнивать WebSocket с обычными HTTP запросами, которые являются однонаправленными, то сразу становится виден очевидный минус HTTP - чтобы узнать об изменении на сервере, необходимо регулярно совершать HTTP запросы и проверять обновления на сервере. При использовании WebSocket сервер может как отвечать на запрос клиента, так и передавать новую информацию.
В связи с этим WebSocket применяется в сервисах, работающих в режиме реального времени - онлайн игры, торговые площадки, биржи. Т.е. где данные меняются очень быстро. Если же нужны статичные данные, или данные, которые обновляются нечасто, то будет достаточно использовать HTTP-запросы.
Чтобы открыть WebSocket-соединение, необходимо использовать специальный протокол ws:// или wss:// Последний использует шифрование, и обладает повышенной надёжностью. Это как https://, но только для WebSocket. Отправляем запрос, сервер с поддержкой WebSocket отвечает - соединение считается установленным. После этого клиент и сервер могут начинать двунаправленный обмен сообщениями.
В нашем случае мы будем использовать крипто-биржу, где данные обновляются очень быстро, а для успешной работы требуется иметь всегда актуальные данные. Как раз в этом случае WebSocket становится незаменимым решением.
ZennoPoster, а так же каждый конкретный шаблон вносят свои коррективы в использование вёб-сокетов - какими-то нюансами можно пренебречь и что-то опустить для упрощения работы. Поэтому на данном этапе общей информации должно быть достаточно.

Практика.

Как правило, у любой крипто-биржи есть документация для разработчиков (если её нет, стоит задуматься имеет ли смысл с ней работать), в которой можно найти информацию как работать c API и WebSocket. Для примера возьмём крипто-биржу ByBit, документацию к которой можно найти тут:
https://bybit-exchange.github.io/docs/spot/v3/#t-introduction
Переходим, ищем раздел по WebSocket и смотрим что нам потребуется:
https://bybit-exchange.github.io/docs/spot/v3/#t-websocket

Для начала нам нужно найти адрес, по которому будет доступен протокол WebSocket.

endpoint.png


Во многих случаях после открытия соединения, оно может автоматически закрываться через определённое количество времени, для проверки соединения используются так называемые «ping-pong фреймы», которые так же могут использоваться для поддержания соединения открытым. Смотрим в документацию:

ping.png


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

json.png


Справа в окне указан пример этого запроса и пример как будет выглядеть ответ. В данном случае нам необходимо указать нужную торговую пару.
Теперь у нас есть все данные для реализации WebSocket соединения и получения данных:

Endpoint: wss://stream.bytick.com/spot/public/v3
Request: {"op":"subscribe","args":["tickers.BTCUSDT"]}
Ping: {"op":"ping"}

В данном эндпоинте я поменял домен с bybit.com на bytick.com, который является зеркалом. По непонятной причине в ZennoPoster домен bybit.com не захотел устанавливать соединение, тогда как вне ZennoPoster он отвечал нормально.

Для удобства составления запросов, представляющих собой JSON и преобразования их в строку, можно использовать любой онлайн-сервис JSON Minifier. Например, этот:
https://codebeautify.org/jsonminifier

json_mini.png


Тестировать будем в довольно удобном расширении для браузера, которое называется WebSocket Test Client:

ws client.png


Скачать его можно тут:
https://chrome.google.com/webstore/detail/websocket-test-client/fgponpodhbmadfljofbimhhlengambbn

Прописываем URL жмём «Open» для открытия соединения. После того как соединение открылось, становится активным поле «Request», куда собственно и прописываем наш request. Нажимаем «Send» и видим в нижнем поле как сервер начинает нам слать данные. Периодически отправляем наш Ping запрос для поддержания соединения открытым.

ws example.png


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

Шаблон.

template.png


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

Пробежимся по настройкам:

settings.png


Первые 3 пункта мы уже рассматривали выше.

Use filter”: выводить в лог не весь ответ сервера, а конкретно по нужному ключу.
Например, у нас идёт следующий ответ от сервера в формате JSON:
{"topic":"bookticker.BTCUSDT","ts":1671558643493,"type":"snapshot","data":{"s":"BTCUSDT","bp":"16798.37","bq":"0.00274","ap":"16800.96","aq":"0.001015","t":1671558643493}}
Мы хотим получать только значения по ключу “bp”. Соответственно прописываем этот ключ в поле “Filter parameter” и в логе будем получать значение только по нему.
Target value”: Если необходимо дождаться определённого значения для ключа, прописываем здесь нужное значение. Как только это значение достигнуто, работа завершается и дальше можно принимать решения исходя из полученных данных.

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

В папке dll находятся библиотеки, которые необходимо скопировать в папку с установленным ZennoPoster - C:\Program Files\ZennoLab\RU\ZennoPoster Pro V7\7.7.1.0\Progs\ExternalAssemblies (путь может отличаться в зависимости от версии установленной программы).

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

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

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

Последнее редактирование модератором:

TommyTuta

Client
Регистрация
02.10.2022
Сообщения
130
Благодарностей
58
Баллы
28
Статья была бы в 100 раз лучше если бы показал как тестировать вебсокеты со своими заголовками/куки при подключении.
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Статья была бы в 100 раз лучше если бы показал как тестировать вебсокеты со своими заголовками/куки при подключении.
Немножко другой уровень. Тут хотел рассмотреть именно работу с несложными сервисами, которые не требуют каких-то дополнительных решений. Как упоминал в самом начале, статья рассчитана на уровень подготовки пользователей ниже среднего, для которых нужно общее понимание - просто выполнить несложные действия и не залезать сильно в дебри.
Но спасибо за замечание, возможно в будущем будет для уровня повыше.
 
  • Спасибо
Реакции: TommyTuta

temass

Client
Регистрация
06.06.2015
Сообщения
98
Благодарностей
3
Баллы
8
Для меня полезно, спасибо
 
  • Спасибо
Реакции: Zedx

radv

Client
Регистрация
11.05.2015
Сообщения
3 788
Благодарностей
1 952
Баллы
113
Спасибо за статью, все руки никак не доходят поизучать вебсокеты )
 
  • Спасибо
Реакции: Zedx

fridayman

Client
Регистрация
25.03.2018
Сообщения
169
Благодарностей
260
Баллы
63
Хороший материал, полезно! Я вот на .net эту тему сразу начал осваивать, так как не было желания вникать в то, как через зеннопостер запускать новые потоки и связывать их одним шаблоном и БД. Но теперь стало чуть более понятно, спасибо!;-)
 
  • Спасибо
Реакции: Zedx

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Хороший материал, полезно! Я вот на .net эту тему сразу начал осваивать, так как не было желания вникать в то, как через зеннопостер запускать новые потоки и связывать их одним шаблоном и БД. Но теперь стало чуть более понятно, спасибо!;-)
Я сначала пишу в VS, а потом адаптирую под зенку и частенько приходится кое-что вырезать, а так же городить костыли. В общем есть как плюсы, так и минусы при работе с зенкой и кодом.
 
  • Спасибо
Реакции: fridayman

usawa0

Client
Регистрация
29.11.2019
Сообщения
59
Благодарностей
22
Баллы
8
Голосую! Актуальная тема
 
  • Спасибо
Реакции: Zedx

MaxMan

Client
Регистрация
15.02.2021
Сообщения
93
Благодарностей
80
Баллы
18
  • Спасибо
Реакции: Zedx

vasyaya

Client
Регистрация
09.02.2015
Сообщения
555
Благодарностей
35
Баллы
28
Спасибо за статью! Классная работа. :bu:

Я заметил что при запуске вебсокета есть задержка до начала получения данных в 2 сек. примерно.
Отсюда и вопрос. Если данные нужны моментально (по 100500 торговым парам по очереди), то как взаимодействовать в 1 шаблоне с вебсокетом?
 
  • Спасибо
Реакции: Zedx

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Спасибо за статью! Классная работа. :bu:

Я заметил что при запуске вебсокета есть задержка до начала получения данных в 2 сек. примерно.
Отсюда и вопрос. Если данные нужны моментально (по 100500 торговым парам по очереди), то как взаимодействовать в 1 шаблоне с вебсокетом?
Спасибо за отзыв.
Задержка обусловлена подключением к вёбсокету, 1 секунда задержки стоит принудительно перед проверкой состояния подключения. Если сильно критично время, то её можно сократить. (79 строка в общем коде Thread.Sleep(1000) вместо 1000 поставить значение в миллисекундах поменьше)
Если нужно получать данные по нескольким парам, то их все можно объединить в одном запросе, например для двух пар будет так:
{"op":"subscribe","args":["bookticker.BTCUSDT","bookticker.ETHUSDT"]}
 
Последнее редактирование:
  • Спасибо
Реакции: Roman* и vasyaya

vasyaya

Client
Регистрация
09.02.2015
Сообщения
555
Благодарностей
35
Баллы
28
Спасибо за отзыв.
Задержка обусловлена подключением к вёбсокету, 1 секунда задержки стоит принудительно перед проверкой состояния подключения. Если сильно критично время, то её можно сократить. (79 строка в общем коде Thread.Sleep(1000) вместо 1000 поставить значение в миллисекундах поменьше)
Если нужно получать данные по нескольким парам, то их все можно объединить в одном запросе, например для двух пар будет так:
{"op":"subscribe","args":["bookticker.BTCUSDT","bookticker.ETHUSDT"]}
Подскажите пожалуйста, почему не приходят данные по wss://stream.binance.com:9443/ws/!miniTicker@arr
В логах пусто
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Подскажите пожалуйста, почему не приходят данные по wss://stream.binance.com:9443/ws/!miniTicker@arr
В логах пусто
Тут немного другой принцип. При обращении к этому эндпоинту сразу начинаем получать данные, без необходимости отправки тела запроса и без пинга. Но шаблон отправляет запрос по умолчанию (или пустую строку вместо запроса), поэтому это приводит к ошибке и закрытию соединения.
Немного подправил шаблон для этого случая. В настройках нужно отключить Send request и Use ping и всё будет работать.
 

Вложения

  • Спасибо
Реакции: paydot и vasyaya

paydot

Client
Регистрация
21.11.2012
Сообщения
56
Благодарностей
1
Баллы
8
как добавить прокси-сервер
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113

Вложения

  • Спасибо
Реакции: paydot

paydot

Client
Регистрация
21.11.2012
Сообщения
56
Благодарностей
1
Баллы
8
Работает отлично, спасибо
 

paydot

Client
Регистрация
21.11.2012
Сообщения
56
Благодарностей
1
Баллы
8
Знаете ли вы данные пинга для binance, я пробовал {"opcode": "0xA"}.
{ "opcode": "pong"}
{ "op": "pong" }
{"event": "pong"} не работает.
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Знаете ли вы данные пинга для binance, я пробовал {"opcode": "0xA"}.
{ "opcode": "pong"}
{ "op": "pong" }
{"event": "pong"} не работает.
Если бы там нужно было отправлять просто пинг, как например в ByBit, то было бы намного проще, т.к. там мы отправляем пинг путём обычного запроса. В бинансе другая ситуация - он сам отправляет пинг, а нам надо отправить понг путём изменения фрейма. Библиотека websocket-sharp, используемая тут, не позволяет изменять фрейм, однако в её последней версии есть такая возможность - там появился внутренний метод WebSocketFrame.CreatePongFrame() не позволяющий отправлять понг вручную, но отправляющий его автоматически после получения пинга.
К сожалению у меня не получилось запустить последнюю версию библиотеки в зеннопостере (постоянно появляется ошибка подключения), причём отдельно от зеннопостера она работает. Возможно это проблема конкретной версии зеннопостера (у меня 7.7.1) и на другой библиотека будет работать.
 

Вложения

  • Спасибо
Реакции: paydot

paydot

Client
Регистрация
21.11.2012
Сообщения
56
Благодарностей
1
Баллы
8
Кажется, что все должно пройти через множество трудностей, прежде чем станет совершенным.
 

Markoonij

Client
Регистрация
13.10.2020
Сообщения
70
Благодарностей
3
Баллы
8
У меня из входных данных есть только endpoint: ws://api.oddscp.com:8005
Но подклюсатся отказывается:
Компиляция кода Ошибка в действии "CS7036" "There is no argument given that corresponds to the required formal parameter 'wsRequest' of 'Ws.WsRequestAsync(string, string, string, bool, string, string)'". [Строка: 4; Cтолбец: 4]
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
У меня из входных данных есть только endpoint: ws://api.oddscp.com:8005
Но подклюсатся отказывается:
Компиляция кода Ошибка в действии "CS7036" "There is no argument given that corresponds to the required formal parameter 'wsRequest' of 'Ws.WsRequestAsync(string, string, string, bool, string, string)'". [Строка: 4; Cтолбец: 4]
Проверил, ошибки нет. Вот скрин настроек шаблона. Возможно необходимо перекачать обновлённую версию, она несколькими постами выше
ws.png
 

Vivi

Client
Регистрация
05.09.2018
Сообщения
45
Благодарностей
1
Баллы
8
Дня 4 назад запускал шаблон, все нормально работало, сейчас снова решил его запустить и пишет Connection failed
Уже пробовал перекачивать,все равно эту ошибку пишет, все настройки по умолчанию ничего не меняю, в браузере через расширение вебсокет работает почему в шаблоне не работает я понять не могу, что то поменять надо?
103851
 
Последнее редактирование:

Markoonij

Client
Регистрация
13.10.2020
Сообщения
70
Благодарностей
3
Баллы
8
Дня 4 назад запускал шаблон, все нормально работало, сейчас снова решил его запустить и пишет Connection failed
Уже пробовал перекачивать,все равно эту ошибку пишет.ю все настройки по умолчанию ничего не меняю, в браузере через расширение вебсокет работает почему в шаблоне не работает я понять не могу, что то поменять надо? Посмотреть вложение 103851
У меня такая же фигня
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Есть такое дело. Учитывая, что шаблон не менялся и используемая библиотека websocket-sharp тоже, а в браузере всё работает, следовательно, какие-то проблемы на стороне зенно.
 

Vivi

Client
Регистрация
05.09.2018
Сообщения
45
Благодарностей
1
Баллы
8
Есть такое дело. Учитывая, что шаблон не менялся и используемая библиотека websocket-sharp тоже, а в браузере всё работает, следовательно, какие-то проблемы на стороне зенно.
предыдущую версию зены установил - не помогло, не пойму это у меня с компом проблемы или вообще глобальная проблема у всех?у всех не работает или только у меня?
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
предыдущую версию зены установил - не помогло, не пойму это у меня с компом проблемы или вообще глобальная проблема у всех?у всех не работает или только у меня?
У меня на нескольких линках не хочет работать - не коннектит, хотя отдельно от зенки эти линки рабочие. Похоже баг репорты писать не имеет смысла, т.к. никто ничего чинить уже не будет в 7й версии. Придётся ждать выхода восьмёрки, которая вроде как пишется с нуля, надеюсь там всё будет работать.
 
  • Спасибо
Реакции: Vivi

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
Нашёл причину - у меня стоит проверка, что соединение живое. Если соединение обрывается, то работа прекращается. Зенка почему-то рвёт соединение, но при этом соединение остаётся активным. В данном случае нужно просто убрать эту проверку в коде (_ws.IsAlive)
 

Vivi

Client
Регистрация
05.09.2018
Сообщения
45
Благодарностей
1
Баллы
8
Нашёл причину - у меня стоит проверка, что соединение живое. Если соединение обрывается, то работа прекращается. Зенка почему-то рвёт соединение, но при этом соединение остаётся активным. В данном случае нужно просто убрать эту проверку в коде (_ws.IsAlive)
убрал но чето соединение успешно но дальше в лог ничего не пишется, хотя галка стоит и таргет убрал, оставил пустым, чето все равно не то, в лог же должно все писаться как я понял
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 346
Благодарностей
910
Баллы
113
убрал но чето соединение успешно но дальше в лог ничего не пишется, хотя галка стоит и таргет убрал, оставил пустым, чето все равно не то, в лог же должно все писаться как я понял
Можешь скинуть в лс свой линк, проверим, в чём может быть проблема
 

Vivi

Client
Регистрация
05.09.2018
Сообщения
45
Благодарностей
1
Баллы
8
Можешь скинуть в лс свой линк, проверим, в чём может быть проблема
да я тот же самый который в проекте используется, wss://stream.bytick.com/spot/public/v3
я просто не пойму почему так, я когда первый раз проект запускал, у меня в логе все прям писалось все нормально было. потом через 4-5 дней запускаю снова и у меня было конекшин файлид, хотя абсолютно ничего не менял за это время, вот и понять не могу что происходит_)))
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)