5 место Асинхронный Websocket для вас и ваших близких

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
Здарова, братцы. :-)

Я так вдохновился вашими положительными отзывами на предыдущую статью, что решил поделиться ещё одной. :ay:

Предисловие.
В ноябре прошлого года у меня была одна удалённая работёнка, в которой мне потребовался ZennoPoster. Задача состояла в продвижении криптопроекта на ресурсах, где может находиться целевая аудитория. Одним из таких ресурсов был Discord, автоматизацию которого я стал реализовывать на стандартных кубиках. По сути с этого момента и началось моё изучение ZP.

Прошло несколько месяцев и от работы не осталось и следа, зато остался ZennoPoster с уже написанным Discord. Нужен был новый источник дохода, и после нескольких профитных тестов я решил реализовать регистратор и рассыльщик на запросах, дабы запустить больше потоков на паре моих ПК оставшихся после майнинга. Спустя некоторое время задача была реализована и трафик полился, а с ним и профит, но затем Discord стал запрашивать авторизацию, тут и началось моё изучение Websocket.

WebSocket — протокол связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени. (c)Википедия

WS в основном используется на ресурсах, где необходим активный обмен данными. Это могут быть мессенджеры, онлайн-игры, форексы и различные приложения, где важно обмениваться большим объёмом данных в режиме реального времени.
Клиент (браузер или приложение) с помощью WS подключается к серверу только один раз и внутри этого подключения обменивается данными.
За счет этого уменьшается объём передаваемого трафика, и тем самым WS имеет огромное преимущество перед обычными POST/GET запросами, где нужно постоянно устанавливать новые подключения и передавать заголовки.

По сути WS похож на обычный POST запрос, но чтобы его выполнить на ZP нам понадобится библиотека. В моём случае это была websocket-sharp.
О том как ей пользоваться я и опишу в этой статье. :df:


Sniffаем.
Проанализировать трафик WS можно разными способами, но самый простой и доступный это использование браузера на базе Chromium. В моём случае это SWIron.
  1. Заходим на discordapp.com
  2. Открываем DevTools нажатием на F12
  3. Переходим на вкладку Network -> WS -> Frames
  4. Регистрируем новый аккаунт и заходим
Должна отобразиться следующая картина:
45838


Разберёмся что здесь к чему.
В колонке Name при наведении отобразится ссылка для запроса, её можно скопировать к себе нажав на пр. кн. мыши и соответствующее меню: wss://gateway.discord.gg/?encoding=json&v=6&compress=zlib-stream
В колонке Data можно увидеть исходящие и поступающие запросы. Копируем себе первый исходящий запрос (это запрос, который мы должны отправить серверу для авторизации):
{"op":2,"d":{"token":"NjMwMTU2ODYzNDcxNjE2MDMw.Xe9SFw.GLgMR8R7vQPnHOmaD5KmHqU4vmk","properties":{"os":"Windows","browser":"Chrome","device":"","browser_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3650.0 Iron Safari/537.36","browser_version":"","os_version":"10","referrer":"","referring_domain":"","referrer_current":"","referring_domain_current":"","release_channel":"stable","client_build_number":50980,"client_event_source":null},"presence":{"status":"online","since":0,"activities":[],"afk":false},"compress":false}}

Теперь мы можем проверить будет ли работать наш WS на отдельном клиенте. Для этого можно использовать расширение Simple WebSocket Client.
  • Прописываем URL
  • Открываем Websocket нажатием на Open (в логах должно появиться первое сообщение с heartbeat_interval)
  • Вставляем тело исходящего запроса в поле Request и нажимаем Send. В логах мы получим ответ, что всё прошло успешно.
45856


Супер! :ay: Всё работает как надо, дело осталось за малым - реализовать тоже самое на ZennoPoster.:du:

Realизуем.
Для начала нам нужен сам websocket-sharp.dll. Качаем и вытаскиваем его с помощью WinRAR. Закидываем библиотеку в папку ExternalAssemblies. Добавляем его в наш проект с помощью блока "Ссылки из GAC" и прописываем using:
Директивы using и общий код:
using WebSocketSharp;
using WebSocketSharp.Server;
using WebSocketSharp.Net;
Сразу закинем тело запроса в переменную wss_data.
45971


Кстати, в тестовом шаблоне я использовал тело запроса от десктопной версии, поэтому просто можете закинуть свой токен в переменную для теста. (build number - версия клиента)
Если взглянуть на трафик в браузере, то можно заметить, что сокет не закрывается и принимает/отправляет периодично новые запросы, поэтому в коде мы должны будем использовать асинхронный метод, чтобы сам шаблон выполнялся, а сокет работал в фоновом режиме и не закрывался, пока мы его об этом не попросим.

В общем коде дописываем using:
using System.Threading.Tasks;
В общем коде в классе CommonCode пишем наш код:
Описываем методы для WSS:
public static void Wss(IZennoPosterProjectModel project) //определяем метод Wss
{
Random rnd = new Random(); //инициализация Random
string data = project.Variables["wss_data"].Value; //загружаем тело запроса из переменной
//подключаем прокси, если необходимо
//string ip = project.Variables["proxy_ip"].Value;
//string login = project.Variables["proxy_login"].Value;
//string pass = project.Variables["proxy_pass"].Value;

using (var ws = new WebSocket("wss://gateway.discord.gg/")) //определяем ссылку запроса
{
//ws.SetProxy (ip, login, pass); //устанавливаем прокси, если необходимо
//ws.SetCookie (new Cookie("__cfduid", project.Variables["cookies_value"].Value)); //устанавливаем куки, если необходимо
ws.Origin = "https://discordapp.com";

ws.OnMessage += (sender, e) => //объявляем, что будем получать сообщение
project.SendInfoToLog(e.Data); //пишем инфу в лог для наглядности
ws.Connect(); //подключаемся по wss
ws.Send (data); //отправляем тело запроса
System.Threading.Thread.Sleep(1000); //небольшая пауза
ws.Send ("{\"op\":4,\"d\":{\"guild_id\":null,\"channel_id\":null,\"self_mute\":true,\"self_deaf\":true,\"self_video\":false}}"); //отправляем тело второго запроса

int q = 0;

while (Convert.ToBoolean(project.Variables["wss_lock"].Value)) //пока переменная = true, цикл будет выполняться
    {
        Thread.Sleep(rnd.Next(40000, 43000));
        q = q + rnd.Next(4, 40);
        ws.Send ("{\"op\":1,\"d\":" + q + "}"); //отправляем тело запроса
     };
}
}

public static async Task WssAsync(IZennoPosterProjectModel project) //определяем асинхронный метод
{
        await Task.Run(() => Wss(project)); //запуск метода Wss
}
Если упрощенно, то сначала вы пишете в методе Wss код, который вы хотите выполнить, а потом в WssAsync указываете, что Wss нужно запустить асинхронно.

Вызвать асинхронный Wss можно с помощью C# кубика.
Подключаемся к Websocket:
CommonCode.WssAsync(project); //запускаем Wss асинхронно
После того как мы присвоим переменной wss_lock значение false через кубик "Обработка переменных", код успешно завершится и websocket закроется. А в Discord ваш аккаунт уйдёт в оффлайн. :bf:
Также завершить поток можно другими интересными и, возможно, более "правильными" способами, но я не сильно углублялся в эту тему.

Запускаем шаблон и проверяем лог в ProjectMaker.
46069


Вот и всё, наш Websocket готов!:bp:

Видео


Summary
В конечном итоге всё оказалось не так уж и сложно, но пришлось разбираться и потратить какое-то время. После чего я успешно возобновил трафик, а позже реализовал рассыльщик по чату в Reddit, там также используется wss. Вообще Websocket часто используют в авторизациях и мессенджерах, поэтому, думаю, эти знания вам пригодятся. ;-)

P.S. Асинхронный WSS гарантированно работает в версии 5.28. Если нужно заменить какие-то заголовки, то можно подредактировать некоторые файлы с Github (например User-Agent) и скомпилировать в VS измененный websocket-sharp.dll.
 
Тема статьи
Другое
Номер конкурса статей
Двенадцатый конкурс статей

Вложения

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

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

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

DenisK

Client
Регистрация
28.06.2016
Сообщения
591
Благодарностей
289
Баллы
63

Manfred

Client
Регистрация
06.08.2019
Сообщения
37
Благодарностей
17
Баллы
8
За вебсокеты спасибо, большущее!
 
  • Спасибо
Реакции: WLDN

Sanekk

Client
Регистрация
24.06.2016
Сообщения
999
Благодарностей
390
Баллы
63
  • Спасибо
Реакции: WLDN

prmaaq

Client
Регистрация
08.05.2014
Сообщения
22
Благодарностей
5
Баллы
3
Интересно, но пока не фига не понятно. :-)
 
  • Спасибо
Реакции: Amigo и WLDN

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93

prmaaq

Client
Регистрация
08.05.2014
Сообщения
22
Благодарностей
5
Баллы
3
Я новичок, поэтому меня собственно говоря интересовала сама причина возникновения этой ситуации, для чего авторы ресурсов используют этот метод и как его диагностировать, определить, что он используется. На мой взгляд именно этой информации не хватает в статье для полноты решения.
 
Последнее редактирование:
  • Спасибо
Реакции: PlayerT7 и WLDN

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
Я новичок, поэтому меня собственно говоря интересовала сама причина возникновения этой ситуации, для чего авторы ресурсов используют этот метод и как его диагностировать определить, что он используется. На мой взгляд именно этой информации не хватает в статье для полноты решения.
Спасибо за полезное замечание, действительно думаю будет полезно добавить эту информацию. :-)
 

Oleg1987

Client
Регистрация
11.08.2014
Сообщения
1 228
Благодарностей
784
Баллы
113
Годнота!!!
 
  • Спасибо
Реакции: WLDN

Dr.Pipetka

Client
Регистрация
12.12.2017
Сообщения
1 307
Благодарностей
865
Баллы
113
Крутяк. +
 
  • Спасибо
Реакции: WLDN

AZANIR

Client
Регистрация
09.06.2014
Сообщения
405
Благодарностей
198
Баллы
43
Плюс в карму , класс !
 
  • Спасибо
Реакции: WLDN

Supergrok

Client
Регистрация
05.03.2019
Сообщения
171
Благодарностей
156
Баллы
43
Пока еще не понял как я буду это применять у себя, буду разбираться и учиться. Спасибо, однозначно в копилку.
 
  • Спасибо
Реакции: WLDN

Finiti

Новичок
Регистрация
27.08.2017
Сообщения
26
Благодарностей
19
Баллы
3
То что надо, плюсую.
 
  • Спасибо
Реакции: WLDN

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 788
Благодарностей
2 453
Баллы
113
WSS уже давно должны были бы сделать стандартным функционалом Зеннопостера как кубики GET, POST, DELETE, OPTION, а также как работа с базой и FTP.
Спасибо за статью!
 

Babulia

Client
Регистрация
18.11.2018
Сообщения
14
Благодарностей
6
Баллы
3
спасибо!!!!!! теперь с биржами по битку можно работать)))))
 
  • Спасибо
Реакции: Finiti и WLDN

Nike59

Client
Регистрация
05.08.2011
Сообщения
122
Благодарностей
122
Баллы
43
Отдельное спасибо за нестандартное (по крайней мере, для меня) использование SWIron в качестве сниффера.
 
  • Спасибо
Реакции: WLDN

ibred

Client
Регистрация
04.04.2015
Сообщения
3 835
Благодарностей
3 552
Баллы
113
Добавлено видео (см. внизу статьи).
 
  • Спасибо
Реакции: WLDN

frion-seo

Client
Регистрация
27.02.2011
Сообщения
538
Благодарностей
471
Баллы
63

one

Client
Регистрация
22.09.2015
Сообщения
6 833
Благодарностей
1 275
Баллы
113
  • Спасибо
Реакции: WLDN

64rus1

Client
Регистрация
13.06.2016
Сообщения
96
Благодарностей
18
Баллы
8
Спасибо
 
  • Спасибо
Реакции: WLDN

Metrix

Client
Регистрация
03.01.2014
Сообщения
343
Благодарностей
272
Баллы
63
Полезная техническая статья, очень пригодится для того чтобы решать вопросы автоматизации на сокетах, ведь всё больше и больше ресурсов их используют. :ay:
 
  • Спасибо
Реакции: WLDN

Чешир

Client
Регистрация
27.06.2014
Сообщения
1 634
Благодарностей
963
Баллы
113
Круто!
 
  • Спасибо
Реакции: WLDN

dimanis

Client
Регистрация
16.04.2016
Сообщения
195
Благодарностей
110
Баллы
43
А как бы получить данные не в лог а в переменную? project.SendInfoToLog(e.Data); шлет в лог, а в переменную (e.Data) не кладется, ошибку выдает что нет переменной 'e' итд

Цепь событий пройти: отправить дата на аунтенификацию, получить ответ, если гуд то выпарсить данные и отправить другое тело и так далее. Может есть пример такой работы?
 
Последнее редактирование:

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
А как бы получить данные не в лог а в переменную? project.SendInfoToLog(e.Data); шлет в лог, а в переменную (e.Data) не кладется, ошибку выдает что нет переменной 'e' итд

Цепь событий пройти: отправить дата на аунтенификацию, получить ответ, если гуд то выпарсить данные и отправить другое тело и так далее. Может есть пример такой работы?
Пришли сюда код, посмотрим.
Вообще если e.Data это тип string, то

project.Variables["peremennaya"].Value = e.Data;

должно работать.
 

dimanis

Client
Регистрация
16.04.2016
Сообщения
195
Благодарностей
110
Баллы
43

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93
код ваш, только вынес для тестов в C#кубик.

Посмотреть вложение 52583Посмотреть вложение 52584

тут https://zennolab.com/discussion/threads/zennoposter-websocket.60366/ человек заморачивался, такая же проблема была
надо убрать строчку для логирования, а на её место строчку с переменной
 

dimanis

Client
Регистрация
16.04.2016
Сообщения
195
Благодарностей
110
Баллы
43
чудеса конечно, но заработало))
 
  • Спасибо
Реакции: WLDN

dimanis

Client
Регистрация
16.04.2016
Сообщения
195
Благодарностей
110
Баллы
43
Пока включен сендинфотулог туда куча данных летит, а если переключить на переменную, то в нее попадает что то толи последнее то ли рандомное...

Может есть пример как цепь событий пройти? отправить дата на аунтенификацию, получить ответ, если гуд то выпарсить данные и отправить другое тело и так далее :bc:
 

leha52rus

Client
Регистрация
01.06.2017
Сообщения
266
Благодарностей
91
Баллы
28
Не совсем ясен момент с капчей, как её обойти работая с Websocket
 

WLDN

Client
Регистрация
09.07.2015
Сообщения
357
Благодарностей
566
Баллы
93

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