MQL5 Asynchronous named pipes?

 

I´m trying to integrate MT5 with an external Named Pipe Server application written in C# through named pipes. The problem is the app requires a Asyncronous named pipe, and I can´t find a way to connect to it from MT5.

I´m using the example from https://www.mql5.com/en/articles/503:

void OnStart()
  {
//--- wait for pipe server
   while(!IsStopped())
     {
      if(ExtPipe.Open("\\\\RemoteServerName\\pipe\\MQL5.Pipe.Server",FILE_READ|FILE_WRITE|FILE_BIN)!=INVALID_HANDLE) break;
      if(ExtPipe.Open("\\\\.\\pipe\\MQL5.Pipe.Server",FILE_READ|FILE_WRITE|FILE_BIN)!=INVALID_HANDLE) break;
      Sleep(250);
     }
   Print("Client: pipe opened");

 C# server source code:

// Delegate for passing received message back to caller
public delegate void DelegateMessage(string Reply);

class PipeServer
{
    public event DelegateMessage PipeMessage;
    string _pipeName;

    public void Listen(string PipeName)
    {
        try
        {
            // Set to class level var so we can re-use in the async callback method
            _pipeName = PipeName;
            // Create the new async pipe 
            NamedPipeServerStream pipeServer = new NamedPipeServerStream(PipeName, 
               PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            // Wait for a connection
            pipeServer.BeginWaitForConnection
            (new AsyncCallback(WaitForConnectionCallBack), pipeServer);
        }
        catch (Exception oEX)
        {
            Debug.WriteLine(oEX.Message);
        }
    }

    private void WaitForConnectionCallBack(IAsyncResult iar)
    {
        try
        {
            // Get the pipe
            NamedPipeServerStream pipeServer = (NamedPipeServerStream)iar.AsyncState;
            // End waiting for the connection
            pipeServer.EndWaitForConnection(iar);

            byte[] buffer = new byte[255];

            // Read the incoming message
            pipeServer.Read(buffer, 0, 255);
            
            // Convert byte buffer to string
            string stringData = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Debug.WriteLine(stringData + Environment.NewLine);

            // Pass message back to calling form
            PipeMessage.Invoke(stringData);

            // Kill original sever and create new wait server
            pipeServer.Close();
            pipeServer = null;
            pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 
               1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            // Recursively wait for the connection again and again....
            pipeServer.BeginWaitForConnection(
               new AsyncCallback(WaitForConnectionCallBack), pipeServer);
        }
        catch
        {
            return;
        }
    }
}

 

MT5 can connect and send a message once, but then hangs at next connection. I searched through documentatin but found no way to open an async named pipe. Ideas?

Communicating With MetaTrader 5 Using Named Pipes Without Using DLLs
Communicating With MetaTrader 5 Using Named Pipes Without Using DLLs
  • 2012.10.15
  • MetaQuotes Software Corp.
  • www.mql5.com
Many developers face the same problem - how to get to the trading terminal sandbox without using unsafe DLLs. One of the easiest and safest method is to use standard Named Pipes that work as normal file operations. They allow you to organize interprocessor client-server communication between programs. Take a look at practical examples in C++ and MQL5 that include server, client, data exchange between them and performance benchmark.
 
newgel:

I´m trying to integrate MT5 with an external Named Pipe Server application written in C# through named pipes. The problem is the app requires a Asyncronous named pipe, and I can´t find a way to connect to it from MT5.

I´m using the example from https://www.mql5.com/en/articles/503:

 C# server source code:

 

MT5 can connect and send a message once, but then hangs at next connection. I searched through documentatin but found no way to open an async named pipe. Ideas?

I have been using asynchronous pipes with MT4, but the code you are referring to seems to be pure synchronous implementation. To open the async pipe you have to pass the OVERLAPPED structure in argument to Kernel32::ReadFile(pipe, structure, size, transfered, overlappedStructure)

Then checking the error Kernel32::GetLastError(), for normal opperation, error is set to ERROR_IO_INCOMPLETE (996) - not connected client, or ERROR_PIPE_CONNECTED 535 - connected client

 
Ovo Cz:

I have been using asynchronous pipes with MT4, but the code you are referring to seems to be pure synchronous implementation. To open the async pipe you have to pass the OVERLAPPED structure in argument to Kernel32::ReadFile(pipe, structure, size, transfered, overlappedStructure)

Then checking the error Kernel32::GetLastError(), for normal opperation, error is set to ERROR_IO_INCOMPLETE (996) - not connected client, or ERROR_PIPE_CONNECTED 535 - connected client
Ovo Cz:

I have been using asynchronous pipes with MT4, but the code you are referring to seems to be pure synchronous implementation. To open the async pipe you have to pass the OVERLAPPED structure in argument to Kernel32::ReadFile(pipe, structure, size, transfered, overlappedStructure)

Then checking the error Kernel32::GetLastError(), for normal opperation, error is set to ERROR_IO_INCOMPLETE (996) - not connected client, or ERROR_PIPE_CONNECTED 535 - connected client

Sorry, did not understand... the C# server code I  included above is for an asynchronous named pipe: 

pipeServer = new NamedPipeServerStream(_pipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte,PipeOptions.Asynchronous );

 My problem is how to open an async named pipe on mql5 client. You seems to make reference to Kernel32.dll. Please note I am NOT importing kernel32.dll. I´m trying to use the native named pipe interface from mql5. And why not use kernel32.dll? Well, because it works just fine on MT4 and on MT5 32 bit versions, but fails miserably on MT5 64 bit. Believe-me, I already tried that. Same code that works fine on MT5 32 bits always return invalid handle on 64 bits. That is why I´m trying build in MT5 CNamePiPe library. Unfortunately, it seems that it also has its own bugs.

Did anyone got MT5 64bits talking to an asynchronous named pipe server?

 

Newgel 

 


 
newgel: ... I am NOT importing kernel32.dll. I´m trying to use the native named pipe interface from mql5.

I see, I did not know that Mql5 had implemented asynchronous file operations. Apologies.

 
newgel:

Thanks for information you provided! I also failed with `CFilePipe` @ MetaTrader 5!

But I succeeded with imported `CreateFileW` and `WriteFile` on Windows 10 x86-64 (MetaTrader 5.00 build 1583) and asynchronous named pipe server (written on pure Windows API).

 
Ruslan Garipov:

Thanks for information you provided! I also failed with `CFilePipe` @ MetaTrader 5!

But I succeeded with imported `CreateFileW` and `WriteFile` on Windows 10 x86-64 (MetaTrader 5.00 build 1583) and asynchronous named pipe server (written on pure Windows API).


Do you mind sharing your working code? I was able to use kernel32.dll based named pipes at Windows 10 x86-64 on previous MT5 versions, but it seems version 1755  64 bits is broken again. I'm able to CreateFileW, but when I try WriteFile I get an access violation error. Funny thing is the same exact code works on MT5 1755 32 bits.


Newgel

 
newgel #:

Do you mind sharing your working code? I was able to use kernel32.dll based named pipes at Windows 10 x86-64 on previous MT5 versions, but it seems version 1755  64 bits is broken again. I'm able to CreateFileW, but when I try WriteFile I get an access violation error. Funny thing is the same exact code works on MT5 1755 32 bits.


Newgel

@newgel were you able to get C# Async Named Pipe aserver interacting with MQL5? Is it possible to share some code please? Thanks
 

I don't know if it still helps somebody but I got some pseudo asynchronous pipe Connection between two metatrader instances running communicating via Server written in C++. The communication pipeline is designed as follows: 


Meta Trader Terminal 1 Provider Script  ---->   C++ Server Script    ----->   Meta Trader Terminal 2 Consumer Script 


1. Download the C++ Server Script from here: https://www.mql5.com/en/articles/503

2. Replace the code of the  downloaded file PipeServer.cpp with the following: 


//+------------------------------------------------------------------+
//|                                                 MQL5 Pipe Server |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#include "stdafx.h"
#include "Pipes\PipeManager.h"

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int PipeServer(void)
  {
    wprintf(L"Price Feed Pipe Server\n");
    //--- create named pipe
    CPipeManager providerManager;
    CPipeManager consumerManager;


    if (!providerManager.Create(L"\\\\.\\pipe\\PriceFeedProvider.Server"))
        return(-1);

    if (!consumerManager.Create(L"\\\\.\\pipe\\PriceFeedConsumer.Server"))
        return(-1);

    //--- wait for client
    char          answer[256];
    double           value = -1.0;

    while (true)
    {
        while (!providerManager.IsConnected()  )
        {
            if (!providerManager.ReadString(answer, _countof(answer) - 1))
            {
                Sleep(100);
                continue;
            }
            wprintf(L"Provider Client: connected as '%S'\n", answer);
        }

        while (!consumerManager.IsConnected())
        {

            if (!consumerManager.ReadString(answer, _countof(answer) - 1))
            {
                Sleep(100);
                continue;
            }
            wprintf(L"Consumer Client: connected as '%S'\n", answer);
        }



        int request = 0;

        consumerManager.Read(&request, sizeof(request));

        if (request == 1 )
        {

            if (!providerManager.Read(&value, sizeof(value)))
            {
                wprintf(L"Server: reading integer failed\n");
                return(-1);
            }

            value = value;
            wprintf(L"Server: Price %e \n", value);

            if (!consumerManager.Send(&value, sizeof(value)))
            {
                wprintf(L"Server: sending price failed\n");
                return(-1);
            }
        }

    }

    //---
    return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int _tmain(int argc, _TCHAR* argv[])
  {
   wprintf(L"MQL5 Pipe Server\n");
   wprintf(L"Copyright 2012, MetaQuotes Software Corp.\n");
//--- create named pipe
   while(true)
     {
      PipeServer();
     }
//---
   return(0);
  }
//+------------------------------------------------------------------+

3. Create Provider MQL5 Programm on Terminal A (Example attached). 

4. Create Consumer MQL5 Programm on Terminal B (Example attached)

5. Compile and execute the modified PipeServer programm.

6. Run the MQL5 Provider Script/Bot. 

7. Run the MQL5 Consumer Script/Bot. 


-> In the given example the Ask Price Tick of terminal A should be plotted by the script of terminal B


I'm not super happy with that solution as I would prefere to have only one named pipe directly between Terminal instances without server. But for prototyping it is fine. 


Alternatively, I got a terminal to terminal pipe running as described here: 


https://www.mql5.com/en/forum/1276/page2#comment_48429368 

Discussion of article "A DLL-free solution to communicate between MetaTrader 5 terminals using Named Pipes"
Discussion of article "A DLL-free solution to communicate between MetaTrader 5 terminals using Named Pipes"
  • 2013.12.06
  • www.mql5.com
New article A DLL-free solution to communicate between MetaTrader 5 terminals using Named Pipes is published: Author: investeo...
Reason: