问题
I'm trying to set up a PUB socket in MQL5 and a SUB socket in Python that will receive messages.
I have this in MQL5:
#include <Zmq/Zmq.mqh>
Context context("helloworld");
Socket socket(context,ZMQ_PUB);
string BROKER;
int OnInit()
{
if (socket.bind("tcp://*:5556"))
{
Print("Error");
}
else
Print("Bound");
BROKER = AccountInfoString(ACCOUNT_COMPANY);
return(INIT_SUCCEEDED);
}
void OnTick()
{
MqlTick last_tick;
string str;
if(SymbolInfoTick(Symbol(),last_tick))
{
StringConcatenate(str, BROKER, ",", Symbol(), ",", last_tick.time_msc, ",", last_tick.ask, ",", last_tick.bid, ",", last_tick.last, ",", last_tick.volume);
}
else
str = "FAIL";
Print(str);
ZmqMsg reply(str);
socket.send(reply);
}
And this in Python:
import zmq
import random
import sys
import time
context = zmq.Context()
socket = context.socket(zmq.SUB)
ports = [5556]
for port in ports:
print(port)
socket.connect("tcp://localhost:{}".format(port))
socket.setsockopt_string(zmq.SUBSCRIBE, '')
print('connected')
f = open('metatrader-1.csv', 'a')
while True:
msg = socket.recv()
print(msg)
f.write(str(msg) + '\n')
This problem is that this does not seem to receive anything on the Python side, the recv call just blocks forever. The OnTick method is fired in MT, since the prints can be seen.
How can I get this to work?
Note that if I switch to a REP/REQ pair, it works.
MQL5:
#include <Zmq/Zmq.mqh>
Context context("helloworld");
Socket socket(context,ZMQ_REQ);
string BROKER;
int OnInit()
{
if (socket.connect("tcp://localhost:5555"))
{
Print("Error");
}
else
Print("Bound");
BROKER = AccountInfoString(ACCOUNT_COMPANY);
return(INIT_SUCCEEDED);
}
void OnTick()
{
MqlTick last_tick;
string str;
if(SymbolInfoTick(Symbol(),last_tick))
{
StringConcatenate(str, BROKER, ",", Symbol(), ",", last_tick.time_msc, ",", last_tick.ask, ",", last_tick.bid, ",", last_tick.last, ",", last_tick.volume);
}
else
str = "FAIL";
Print(str);
ZmqMsg reply(str);
socket.send(reply);
socket.recv(reply);
}
Python:
import zmq
import random
import sys
import time
context = zmq.Context()
socket = context.socket(zmq.REP)
ports = [5555]
for port in ports:
print(port)
socket.bind("tcp://*:{}".format(port))
#socket.setsockopt_string(zmq.SUBSCRIBE, '')
print('connected')
f = open('metatrader-1.csv', 'a')
while True:
msg = socket.recv()
socket.send_string('ack')
print(msg)
f.write(str(msg) + '\n')
But this has some drawbacks so I'd rather not use this if I can help it.
回答1:
Your socket option must be placed before the socket connection, so your code will be:
import zmq
import random
import sys
import time
context = zmq.Context()
socket = context.socket(zmq.SUB)
ports = [5556]
socket.setsockopt(zmq.SUBSCRIBE, b"") # Note.
for port in ports:
print(port)
socket.connect("tcp://localhost:{}".format(port))
print('connected')
f = open('metatrader-1.csv', 'a')
while True:
msg = socket.recv()
print(msg)
f.write(str(msg) + '\n')
Also, this part:
if (socket.bind("tcp://*:5556"))
{
Print("Error");
}
else
Print("Bound");
Should be the other way around. This will actually print an error when the socket is successfully bound.
来源:https://stackoverflow.com/questions/53548582/mql5-zmq-pub-socket-not-being-received-by-python-zmq-sub-socket