Обсуждение статьи "WebSocket для MetaTrader 5 — Использование Windows API"

 

Опубликована статья WebSocket для MetaTrader 5 — Использование Windows API:

В этой статье мы используем WinHttp.dll, чтобы создать клиент WebSocket для MetaTrader 5-программ. В конечном итоге клиент должен быть выполнен в виде класса и протестирован во взаимодействии с WebSocket API от Binary.com.

Ниже показано создание нового пользовательского символа после запуска советника.

EA demo

Автор: Francis Dube

 
Это так здорово, особенно кажется, что он поддерживает безопасный вебсокет.
Работает ли он и для MT4?

Отличная статья, спасибо.
 
Есть ли в этой библиотеке websocket функция для отправки ping и pong?
 

Библиотека (winhttp.dll) не предоставляет никаких функций для пингов или понгов. Хотя в документации упоминается параметр конфигурации, который определяет, как поддерживать соединение. Я полагаю, что библиотека посылает пинги автоматически, когда соединение простаивает.

 
#include<websocket.mqh>
#include<JAson.mqh>
#define  BINANCE_URL "fstream.binance.com:443/ws"


CWebsocket       websocket;    //websocket-клиент
CJAVal           m_jv;         // полезный объект json


//+------------------------------------------------------------------+
//| Функция инициализации эксперта|
//+------------------------------------------------------------------+
int OnInit() {
//--- создайте таймер
   EventSetTimer(1);

//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Функция деинициализации эксперта|
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--- уничтожить таймер
   EventKillTimer();

}

//+------------------------------------------------------------------+
//| Функция таймера|
//+------------------------------------------------------------------+
void OnTimer() {

   if(!websocket.Connect(BINANCE_URL)) {
      Print(websocket.LastErrorMessage()," : ",websocket.LastError());
      return;
   } else {
      Print("Connected");
   }

}
//+------------------------------------------------------------------+

Я просто пытаюсь проверить, подключается ли он, но он выдает ошибку при подключении

Ошибка: Win32 API error 6 : 6

Любая идея, почему он бросает ошибку?

Спасибо

 
Dark Ryd3r проверить, подключается ли он, но он дает ошибку при подключении

Ошибка: Win32 API error 6 : 6

Есть идеи, почему он бросает ошибку?

Спасибо

У меня такая же проблема на mql5, когда я использовал его для подключения к localhost 127.0.0.1 . Однако, когда я попытался использовать его на mql4, он работал нормально !!!!.

Также есть проблема в использовании WinHttpSocketReceive() в событии OnTimer. Это просто приводит к зависанию терминала.

Я построил свой собственный WS сервер, используя nodeJS Express и библиотеку WS, и я успешно смог отправлять на сервер и получать с сервера, когда я добавил функцию Receive в обработчик события onClick, это из-за того, что winhttp.sll::WinHttpSocketReceive() работает асинхронно

что означает, что она не возвращается, пока не получит данные от сервера. Поэтому ее использование непосредственно в onTimer() без отправки данных от сервера приведет к вечной блокировке потока и зависанию терминала.






Таким образом, WinHttpSocketReceive() работает хорошо, когда есть данные от сервера. Но с другой стороны, когда та же функция используется внутри обработчика события OnTimer(), она приводит к зависанию терминала. Есть ли у кого-нибудь подсказка, как этого избежать?

 
Это "блокирующий" вызов метода/функции, здесь ничего не нужно исправлять.
 
Soewono Effendi #:
Это "блокирующий" вызов метода/функции, здесь ничего не исправить.

Да, я знаю, что это синхронная функция, которая блокирует поток, однако мне удалось использовать ее асинхронно, добавив WINHTTP_FLAG_ASYNC в функцию WinnHttpOpen(), и она не блокирует остальную часть кода, однако я столкнулся с другой проблемой, которая возникла после добавления WINHTTP_FLAG_ASYNC, которая, согласно msdn, Мы должны использовать WinHttpSetStatusCallBack() которая принимает указатель на функцию обратного вызова, которая получает результаты.

Я использовал typedef для определения указателя на функцию таким образом

typedef void(*WINHTTP_STATUS_CALLBACK)(HINTERNET,DWORD&,DWORD,BYTE &[],DWORD);

Затем я импортировал WinHttpSetStatusCallBack() из winhttp.dll в соответствии с msdn

https:// docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetstatuscallback

#import

  WINHTTP_STATUS_CALLBACK WinHttpSetStatusCallback(HINTERNET hInternet,WINHTTP_STATUS_CALLBACK lpfnInternetCallback,DWORD dwNotificationFlags,DWORD &dwReserved);

#import

И тут возникает самая большая проблема, которая кажется нерешаемой из-за mql. Когда я компилирую, я получаю сообщение об ошибке, что указатели не разрешены в операторе импорта .!!!!!! поэтому нет возможности передать обратный вызов этой функции, а также указатель на возврат этой функции. Есть идеи ???

WinHttpSetStatusCallback function (winhttp.h) - Win32 apps
WinHttpSetStatusCallback function (winhttp.h) - Win32 apps
  • 2021.10.13
  • stevewhims
  • docs.microsoft.com
The WinHttpSetStatusCallback function sets up a callback function that WinHTTP can call as progress is made during an operation.
 
Kareem Abdelhakim #:

Я использовал typedef для определения указателя на функцию таким образом

затем я импортировал WinHttpSetStatusCallBack() из winhttp.dll в соответствии с msdn

Да, хорошая попытка :)
Я тоже надеялся, что это возможно, но если поискать по форуму, то можно найти, что функция в MQL - это хэндл, а не адрес памяти, как того требует "C/C++" callback-API.

Может быть, когда-нибудь MQL добавит "настоящий" Function Pointer.

 
Soewono Effendi #:

Да, хорошая попытка :)
Я тоже надеялся, что это возможно, но если поискать по форуму, то можно найти, что функция в MQL - это хэндл, а не адрес памяти, как того требует "C/C++" callback-API.

Может быть, когда-нибудь MQL добавит "настоящий" Function Pointer.

Да, я надеюсь, что скоро это будет поддерживаться нативно

 

@Francis Dube Возможно ли создать MQL5-сервис, выполняющий роль WebSocket-сервера? Есть ли у вас примеры?