Ali Hesari
Ali Hesari

Reputation: 1949

Send response to MetaTrader by Node.js TCP server

In MetaTrader 5 I write data to a socket like MQL5 Document example in an Expert Advisors and the data sent to a Node.js TCP server like a charm. But MetaTrader cannot get the response. I don't know what's wrong. If anyone can advise on this.

MQL5 Expert code:

//+------------------------------------------------------------------+ 
//|                                                SocketExample.mq5 | 
//|                        Copyright 2018, MetaQuotes Software Corp. | 
//|                                             https://www.mql5.com | 
//+------------------------------------------------------------------+ 
#property copyright   "Copyright 2018, MetaQuotes Software Corp." 
#property link        "https://www.mql5.com" 
#property version     "1.00" 
#property description "Add Address to the list of allowed ones in the terminal settings to let the example work" 
#property script_show_inputs 

input string Address="127.0.0.1"; 
input int    Port   =3100; 
bool         ExtTLS =false; 
//+------------------------------------------------------------------+ 
//| Send command to the server                                       | 
//+------------------------------------------------------------------+ 
bool HTTPSend(int socket,string request) 
  { 
   char req[]; 
   int  len=StringToCharArray(request,req)-1; 
   if(len<0) 
      return(false); 
//--- if secure TLS connection is used via the port 443 
   if(ExtTLS) 
      return(SocketTlsSend(socket,req,len)==len); 
//--- if standard TCP connection is used 
   return(SocketSend(socket,req,len)==len); 
  } 
//+------------------------------------------------------------------+ 
//| Read server response                                             | 
//+------------------------------------------------------------------+ 
bool HTTPRecv(int socket,uint timeout) 
  { 
   char   rsp[]; 
   string result; 
   uint   timeout_check=GetTickCount()+timeout; 
//--- read data from sockets till they are still present but not longer than timeout 
   do 
     { 
      uint len=SocketIsReadable(socket); 
      if(len) 
        { 
         int rsp_len; 
         //--- various reading commands depending on whether the connection is secure or not 
         if(ExtTLS) 
            rsp_len=SocketTlsRead(socket,rsp,len); 
         else 
            rsp_len=SocketRead(socket,rsp,len,timeout); 
         //--- analyze the response 
         if(rsp_len>0) 
           { 
            result+=CharArrayToString(rsp,0,rsp_len); 
            //--- print only the response header 
            int header_end=StringFind(result,"\r\n\r\n"); 
            if(header_end>0) 
              { 
               Print("HTTP answer header received:"); 
               Print(StringSubstr(result,0,header_end)); 
               return(true); 
              } 
           } 
        } 
     } 
   while(GetTickCount()<timeout_check && !IsStopped()); 
   return(false); 
  } 
//+------------------------------------------------------------------+ 
//| Script program start function                                    | 
//+------------------------------------------------------------------+ 
void OnTick() 
  { 
    double closePrice = iClose(Symbol(), Period(), 0);
    string priceStr = DoubleToString(closePrice);

   int socket=SocketCreate(); 
//--- check the handle 
   if(socket!=INVALID_HANDLE) 
     { 
      //--- connect if all is well 
      if(SocketConnect(socket,Address,Port,1000)) 
        { 
         Print("Established connection to ",Address,":",Port); 

         string   subject,issuer,serial,thumbprint; 
         datetime expiration; 
         //--- if connection is secured by the certificate, display its data 
         if(SocketTlsCertificate(socket,subject,issuer,serial,thumbprint,expiration)) 
           { 
            Print("TLS certificate:"); 
            Print("   Owner:  ",subject); 
            Print("   Issuer:  ",issuer); 
            Print("   Number:     ",serial); 
            Print("   Print: ",thumbprint); 
            Print("   Expiration: ",expiration); 
            ExtTLS=true; 
           } 
         //--- send GET request to the server 
         if(HTTPSend(socket, priceStr)) 
           { 
            Print("GET request sent"); 
            //--- read the response 
            if(!HTTPRecv(socket,1000)) 
               Print("Failed to get a response, error ",GetLastError()); 
           } 
         else 
            Print("Failed to send GET request, error ",GetLastError()); 
        } 
      else 
        { 
         Print("Connection to ",Address,":",Port," failed, error ",GetLastError()); 
        } 
      //--- close a socket after using 
      SocketClose(socket); 
     } 
   else 
      Print("Failed to create a socket, error ",GetLastError()); 
  } 
//+------------------------------------------------------------------+

This Expert contains two methods to send and get data over the socket. HTTPSend Write data to socket and HTTPRecvRead server response and get data from the socket but this method return false and this message Failed to get a response, error 5275.

Node.js server code:

const net = require('net');
const port = 3100;
const host = '127.0.0.1';

const server = net.createServer();
server.listen(port, host, () => {
    console.log('TCP Server is running on port ' + port + '.');
});

let sockets = [];

server.on('connection', function(sock) {
    console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
    sockets.push(sock);

    sock.on('data', function(data) {
        console.log('DATA ' + sock.remoteAddress + ': ' + data);
        // Write the data back to all the connected, the client will receive it as data from the server
        sockets.forEach(function(sock, index, array) {
            sock.write(sock.remoteAddress + ':' + sock.remotePort + " said " + data + '\n');
        });
    });

    // Add a 'close' event handler to this instance of socket
    sock.on('close', function(data) {
        let index = sockets.findIndex(function(o) {
            return o.remoteAddress === sock.remoteAddress && o.remotePort === sock.remotePort;
        })
        if (index !== -1) sockets.splice(index, 1);
        console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
    });
});

Upvotes: 0

Views: 2017

Answers (1)

Angevoyageur
Angevoyageur

Reputation: 21

Error 5275 is "No data on certificate protecting the connection" See mql5 documentation It seems the client code is trying to use a secured connection while your server doesn't ? You need to debug the code to check what is happening there.

Anyway, you copied the code from the documentation, but you will need to customize it, mainly HTTPRecv to parse correctly the answer from your Node.js server. This code, as is, will only print the HTTP headers from the answer to the log.

However, it seems to me you are trying to use an HTTP protocol on client side, while your server is only using TCP ? Unfortunately I don't have exeprience with Node.js so can't help more on this.

Upvotes: 1

Related Questions