I just want to send a message from MetaTrader Terminal, using it`s MQL4/5 to Python, just a simple client server, in which MQL4/5 is a client that sends, and python is a server who receives and these two are syncing with ZeroMQ.
The Python side code is this which I am sure this part is working fine:
import zmq
import time
context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://127.0.0.1:9999")
print("Server Started")
while True:
message = socket.recv() # Wait for next request from client
print("Received request: ", message)
time.sleep (1)
socket.send_string("World")
the MQL4/5 side is this:
Context context( "helloworld" );
Socket socket( context, ZMQ_REQ );
Print( "Connecting to hello world server…" );
socket.connect( "tcp://127.0.0.1:9999" );
while ( True )
{
ZmqMsg request( "Hello" );
socket.send( request );
ZmqMsg reply;
socket.recv( reply ); // Get the reply.
Sleep( 1000 );
}
it seems like MQL4/5 doesn't send anything.
Can you say what is wrong with it?
A few things to start with on MQL4/5-side :
MetaTrader Terminal can operate the compiled MQL4/5 language in several, quite different code-execution modes.
If this was tried in
Script
, the damages are less cardinal than if this would be inExpertAdvisor
and worst side-effects would happen if this was run in someCustomIndicator
-type-of-MQL4/5-code.On ZeroMQ-side :
In any case,
REQ/REP
Built-in Scalable Formal Communication Archetype pattern is a worst case choice, as in many previous posts, there has been explained how fragile this built-in was and that it can easily fall into a principally un-salvageable mutual dead-lock juxtaposition, so better re-read these posts and try to avoid this risk before going into production-grade service desing and implementation.Always setup
socket.setsockopt( zmq.LINGER, 0 )
, both on MQL4/5 and Python sides. No exceptions, no excuse.A setup with
socket.setsockopt( zmq.COMPLETE, 1 )
, both on MQL4/5 and Python sides is also more than adviseable.ZeroMQ language-specific bindings for MQL4/5 :
As there are several active bindings available for MQL4/5
#import
-ed mediations between MetaTrader Terminal MQL4/5 code-execution ecosystem and the ZeroMQ API v.X.Y.Z DLL-library, there is not possible ATM to go into more details. Having used API v2.1.11 ( I had modified the.MQH
-file for solving#import
-ed interface incompatibilities introduced into the game with New-MQL4.56789
changed game - asstring
actually stopped being astring
and some others ) and having seen other bindings, up to the ZeroMQ API v.4.2.+, there are differences to know about in detail, if going beyond a just "Helloworld
"-example.Yet,
Context()
instance initiation ought be equipped with appropriate settings / parameters and when testing, your code should routinely acquire all return-codes + handle all exceptions programmatically ( at leastPrint()
them into log for further debugging with FILE and LINE ).Also use
#import
-ed functionint aZmqERROR = zmq_errno();
, wherever your doubts may spring out, so as to know there was no ZeroMQ error state related right before / after a call took place, or to know exactly what was ZeroMQ signalling from its internal layers, that may have prevented an API call to deliver an expected functional state / result. An MQL4/5-sidestring Zmq::errorMessage( int error )
is ready to advice on some more human readable hints on observing any such ZeroMQ-side error-flag.Last, but not least :
also check the localhost FireWall-configuration, if the TCP
port# == 9999
was actually free to be used, or if the administrative bans on the FireWall security policies did actually prevent any attempt from successfully going and use this port#.Until validated in public, better terminate each
Context()
-instance explicitly and with due care ( after having explicitly.close()
-ed all locally created ZeroMQ-Socket()
-instances. Nasty things could have happended in the earlier API versions, so better be systematic and defensive in all newer API-versions, even if examples or posted code does not do this systematically.