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

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 177
Благодарностей
816
Баллы
113
два раза щелкни на запросе websocket, она и появится, ну у меня по крайней мере так :bn:
UPD. Разобрался, оказывается надо на сам значёк в запросе нажать, чтобы открылась эта нужная вкладка. Непонятно, зачем её было так скрывать.
 
Последнее редактирование:
  • Спасибо
Реакции: orka13

p-sergei

Client
Регистрация
20.12.2016
Сообщения
523
Благодарностей
255
Баллы
63
  • Спасибо
Реакции: orka13

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
Огонь! Спасибо большое! Хоть что-то стало понятно в этих сокетах. То, что нужно! +1 в карму )
 

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
Начал копать инфу. Нашел еще одно классное видео по сокетам. Не сложно и понятно.
 
  • Спасибо
Реакции: WLDN

bad robot

Client
Регистрация
07.03.2011
Сообщения
177
Благодарностей
28
Баллы
28
Может кто-нибудь подкинуть готовый код вывода трафика дискорда не в лог, а в переменную. К сожалению, своих скиллов не хвататет адаптировать приведенный код.
 

porileenvej

Client
Регистрация
09.05.2020
Сообщения
99
Благодарностей
130
Баллы
33
Может кто-нибудь подкинуть готовый код вывода трафика дискорда не в лог, а в переменную. К сожалению, своих скиллов не хвататет адаптировать приведенный код.
Создать список.
В общем коде заменить
C#:
project.SendInfoToLog(e.Data);
на
C#:
project.Lists["Список 1"].Add(e.Data);
 
  • Спасибо
Реакции: marushin, kem и bad robot

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
Последнее редактирование:

Gor

Client
Регистрация
30.09.2016
Сообщения
248
Благодарностей
30
Баллы
28
Взял шаб из топика. Чуть подправил, сделал по образу и подобию. Нужно отправить по адресу
wss://ws.dream-singles.com/ws
вот эти данные:
{"type":"auth","connection":"invite","subscribe_to":["auth-response","chat-invites-response","user-matches-response","presence-change","system-message"],"payload":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ3d3cuZHJlYW0tc2luZ2xlcy5jb20iLCJhdWQiOiJkbV9jaGF0IiwiaWF0IjoxNjExNjU5ODYwLCJleHAiOjE2MTI3NzE4NjAsInN1YiI6IjU1NTE3ODgiLCJnZW5kZXIiOiJtIn0.WNcSP7VFacYdj1D9qnGCsovjaw1oJA7-FMhKVLXtuJg"}
В результате должно получиться следующее:
71302

Исправленный код:
C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;
using ZennoLab.CommandCenter;
using ZennoLab.InterfacesLibrary;
using ZennoLab.InterfacesLibrary.ProjectModel;
using ZennoLab.InterfacesLibrary.ProjectModel.Collections;
using ZennoLab.InterfacesLibrary.ProjectModel.Enums;
using ZennoLab.Macros;
using Global.ZennoExtensions;
using ZennoLab.Emulation;
using WebSocketSharp;
using WebSocketSharp.Server;
using WebSocketSharp.Net;
using System.Threading.Tasks;


namespace ZennoLab.OwnCode
{

    public class CommonCode
    {
        public static void Wss(IZennoPosterProjectModel project) //определяем метод Wss
        {
            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://ws.dream-singles.com/ws")) //определяем ссылку запроса
            {
                try
                {
                    //ws.SetProxy (ip, login, pass); //устанавливаем прокси, если необходимо
                    //ws.SetCookie (new Cookie("__cfduid", project.Variables["cookies_value"].Value)); //устанавливаем куки, если необходимо
                    ws.Origin = "https://www.dream-singles.com";
    
                    ws.OnMessage += (sender, e) => //объявляем, что будем получать сообщение
                    project.SendInfoToLog(e.Data); //пишем инфу в лог для наглядности
                    ws.Connect(); //подключаемся по wss
                    System.Threading.Thread.Sleep(1000); //небольшая пауза
                    ws.Send (data); //отправляем тело запроса
    
                    while (Convert.ToBoolean(project.Variables["wss_lock"].Value)) //пока переменная = true, цикл будет выполняться
                    {
                        Thread.Sleep(2000);
                    };
                    project.SendInfoToLog("Закрытие соединения", true);
                    ws.Close();
                }
                catch (Exception ex)
                { project.SendInfoToLog(ex.Message, true); }
            }
        }
        public static async Task WssAsync(IZennoPosterProjectModel project) //определяем асинхронный метод       
        {           
           await Task.Run(() => Wss(project)); //запуск метода Wss             
        }
    }
}

Никакого положительного ответа от сервера нет (( Как бы мне развязать ему язык? ))

Может быть нужно еще какие-то данные прописать для настройки соединения? Ниже скрин снифинга:
71304
 

Вложения

  • 15,1 КБ Просмотры: 134

loshpek

Client
Регистрация
24.11.2016
Сообщения
83
Благодарностей
34
Баллы
18
Народ, ни у кого не появляются лаги на сервере при работе через либу websocket-sharp?
 

p-sergei

Client
Регистрация
20.12.2016
Сообщения
523
Благодарностей
255
Баллы
63
Народ, ни у кого не появляются лаги на сервере при работе через либу websocket-sharp?
а что за лаги то? За соединениями через библиотеку надо тщательно следить, особенно при некорректных завершениях работы шаблона - соединение так и останется открытым и будет работать асинхронно дальше! В логике работы в таких случаях надо не забыть закрыть соединение! Может таких незакрытых соединений накапливается куча и начинает что-то лагать? :bk:
 

paydot

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

kitkv

Client
Регистрация
26.07.2021
Сообщения
17
Благодарностей
1
Баллы
3
Добрый день. А как поступить если после авторизации нужно отправлять запросы до/после определенного события. Например в срм при открытии карточки заказа происходит обмен сообщениями в сокете, и при сохранении также. Понял что это можно отслеживая значения переменных, но как это реализовать общем коде?
 

loshpek

Client
Регистрация
24.11.2016
Сообщения
83
Благодарностей
34
Баллы
18
Добрый день. А как поступить если после авторизации нужно отправлять запросы до/после определенного события. Например в срм при открытии карточки заказа происходит обмен сообщениями в сокете, и при сохранении также. Понял что это можно отслеживая значения переменных, но как это реализовать общем коде?
Записывай значение e.Data с событитя OnMessage в переменную и потом работай с ней.
 

kitkv

Client
Регистрация
26.07.2021
Сообщения
17
Благодарностей
1
Баллы
3

TheBoss

Client
Регистрация
30.03.2015
Сообщения
529
Благодарностей
193
Баллы
43
Здарова, братцы. :-)

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

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

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




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.
Приветствую! Отличная статья... Используя данный метод для своих целей, а именно делаю вебхук дискорда для получения сигналов определенных с трейдинг вью. Сигнал получается приходят в чат дискорда и уже в шаблоне я передаю это дело в переменную.

Столкнулся с проблемой, что вебсокет каждые пару минут вырубается или соединение теряется или что-то.... не подскажешь что изменить надо, что соединения было постоянным?

У всех так ребят? Вроде как вебсокет должен как раз постоянно быть на готове принять и отдать или не?))
 
Последнее редактирование:

TheBoss

Client
Регистрация
30.03.2015
Сообщения
529
Благодарностей
193
Баллы
43

BAZAg

Client
Регистрация
08.11.2015
Сообщения
1 760
Благодарностей
2 398
Баллы
113
Вообщем я выявил, что каждый 2 минуты происходит сбой. Кто знает выход?
А Вы в течении этих 2х минут какой-то Ping/Pong отправляете/получаете?
Просто чтобы это работало нужно как-бы дать серверу знать, что я мол ещё живой...
 

TheBoss

Client
Регистрация
30.03.2015
Сообщения
529
Благодарностей
193
Баллы
43
А Вы в течении этих 2х минут какой-то Ping/Pong отправляете/получаете?
Просто чтобы это работало нужно как-бы дать серверу знать, что я мол ещё живой...
Да, там в самом шаблоне от ТС есть тема, что он шлет запросики... но это не помагает.
 

Zedx

Client
Регистрация
12.06.2018
Сообщения
1 177
Благодарностей
816
Баллы
113
Приветствую! Отличная статья... Используя данный метод для своих целей, а именно делаю вебхук дискорда для получения сигналов определенных с трейдинг вью. Сигнал получается приходят в чат дискорда и уже в шаблоне я передаю это дело в переменную.

Столкнулся с проблемой, что вебсокет каждые пару минут вырубается или соединение теряется или что-то.... не подскажешь что изменить надо, что соединения было постоянным?

У всех так ребят? Вроде как вебсокет должен как раз постоянно быть на готове принять и отдать или не?))
У меня на одном сайте соединение закрывается через минуту после открытия, каждую минуту необходимо отправлять специальный рефреш запрос, чтобы поддерживать активность соединения. Тут скорее всего такой же случай.
 
Последнее редактирование:
  • Спасибо
Реакции: TheBoss

seomr

Client
Регистрация
31.05.2011
Сообщения
103
Благодарностей
5
Баллы
18
Приветствую, спасибо за статью. Сейчас пытаюсь разобраться в работе с одним сайтом, использующим вебсокет, но никак не выходит. Нужно отправить три сообщения. Первое содержит токен, второе и третье его уже не содержит. При попытке отправки второго или третьего сообщение выкидывает ошибку: 4003 Error: Not authenticated.
Cookies запрос не использует. В headers есть только параметр Sec-WebSocket-Key. Однако, как я понял в этой библиотеке не предусмотрена установка пользовательских заголовков. Как отправить всю цепочку сообщений без сбоя коннекта и возвратом нужных мне данных пока въехать не могу. Если кто-то сталкивался с этим - напишите, пожалуйста, хотя бы в какую сторону смотреть.
 

rol

Client
Регистрация
19.09.2017
Сообщения
42
Благодарностей
7
Баллы
8
Всем привет подскажите если каждые 30 сек поток останавливается и нужно отправлять "primus::pong:: куда прописать что бы отправка шла каждые 30 сек или нужно все перезапускать постоянно
 

Evgeni215873

Client
Регистрация
20.05.2022
Сообщения
19
Благодарностей
2
Баллы
3
так и не понял, для чего шаблон=)
 

Zedx

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

Evgeni215873

Client
Регистрация
20.05.2022
Сообщения
19
Благодарностей
2
Баллы
3

Kinomanius

Активный пользователь
Регистрация
20.01.2020
Сообщения
184
Благодарностей
26
Баллы
28
Что делать если ответ вебсокета в binary message?
 

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