Discussion of article "Websockets for MetaTrader 5 — Using the Windows API"

MetaQuotes
Moderator
250693

New article Websockets for MetaTrader 5 — Using the Windows API has been published:

In this article we will use the WinHttp.dll to create a websocket client for MetaTrader 5 programs. The client will ultimately be implemented as a class and also tested against the Binary.com websocket API.

Running the EA results in the creation of a new custom symbol as shown here.

EA demo

Author: Francis Dube

Soewono Effendi
4941
This is so cool, especially it seems to support secure websocket too.
Does it works for MT4 too ?

Great article, thank you.
Dark Ryd3r
2640
Dark Ryd3r  
Does this websocket library have function for sending ping and pong?
Francis Dube
88846
Francis Dube  

The library (winhttp.dll) does not expose any functions for pings or pongs. Although the documentation refers to a configuration option which governs how the connection is kept alive. I believe the library sends pings automatically when a connection is idle.

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


CWebsocket       websocket;    //websocket client
CJAVal           m_jv;         //utility json object


//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
//--- create timer
   EventSetTimer(1);

//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
//--- destroy timer
   EventKillTimer();

}

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer() {

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

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

Im just trying to check if it connects but Its giving error on connecting

Error: Win32 API error 6 : 6

Any idea why its throwing the error?

Thanks

Kareem Abdelhakim
9576
Dark Ryd3r #:

Im just trying to check if it connects but Its giving error on connecting

Error: Win32 API error 6 : 6

Any idea why its throwing the error?

Thanks

I'm having the same issue on mql5 when used it to connect to a localhost 127.0.0.1  . However When i tried to use it on mql4 it worked normally !!!!. 

Also there is a problem  in using WinHttpSocketReceive() in the OnTimer Event . it simply causes the terminal to freeze . 

i Built my own WS server using nodeJS Express and WS library, and i successfully was able to send to the server and receive from the server when i added the Receive function in the onClick event handler , that is because of the fact that winhttp.sll::WinHttpSocketReceive() works asynchronously 

which means it doesn't return until it receives some data from the server . So using it directly in the onTimer() without having the server to send data will block the thread forever and cause the terminal to freeze . 






So the WinHttpSocketReceive() works well when there is a data from server . But on the other hand when the same function is used inside of OnTimer() Event handler it freezes the terminal . Does anyone have a clue on how to avoid that ?

Soewono Effendi
4941
It is a "blocking" method/function call, nothing to fix here.
Kareem Abdelhakim
9576
Soewono Effendi #:
It is a "blocking" method/function call, nothing to fix here.

Yea i know it's a synchronous function which blocks the thread , however i was able to manage using it asynchronously by adding the WINHTTP_FLAG_ASYNC to the WinnHttpOpen() function and it doesn't block the rest of the code , However i faced another issue that rose by adding WINHTTP_FLAG_ASYNC which is according to msdn , We have to use WinHttpSetStatusCallBack() which takes pointer to a  Call back function that receives the results  . 

I used typedef to define the pointer to the function this way

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

then i imported the WinHttpSetStatusCallBack() from winhttp.dll according to the 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

here comes the biggest issue that seems unresolvable due to mql . when i compile i get error message that pointers are not allowed in the import statement .!!!!!! so there is no way to  pass the call back to this function as well as return pointer to that function . any idea ???

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.
Soewono Effendi
4941
Kareem Abdelhakim #:

I used typedef to define the pointer to the function this way

then i imported the WinHttpSetStatusCallBack() from winhttp.dll according to the msdn

Yeah, nice try :)
I was hoping this would be possible too, but if you search the forum, you'll find that function in MQL is a handle, not a memory address, which is required by "C/C++" callback-API.

Maybe someday MQL would add "real" Function Pointer.

Kareem Abdelhakim
9576
Soewono Effendi #:

Yeah, nice try :)
I was hoping this would be possible too, but if you search the forum, you'll find that function in MQL is a handle, not a memory address, which is required by "C/C++" callback-API.

Maybe someday MQL would add "real" Function Pointer.

yea i hope soon this will be natively supported

Faisal Mahmood
288
Faisal Mahmood  

@Francis Dube Is it possible to create a MQL5 service that acts as the WebSocket server? Do you have some examples?