Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字
Posted
技术标签:
【中文标题】Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字【英文标题】:MQL5 Zmq PUB socket not being received by Python zmq SUB socket 【发布时间】:2018-11-29 22:33:19 【问题描述】:我正在尝试在 MQL5 中设置一个 PUB 套接字,并在 Python 中设置一个将接收消息的 SUB 套接字。
我在 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);
这在 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')
这个问题是这似乎在 Python 端没有收到任何东西,recv 调用只是永远阻塞。 OnTick 方法在 MT 中触发,因为可以看到打印。
我怎样才能让它工作?
请注意,如果我切换到 REP/REQ 对,它会起作用。
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')
但这有一些缺点,所以如果我能帮上忙,我宁愿不使用它。
【问题讨论】:
【参考方案1】:您的套接字选项必须放在套接字连接之前,因此您的代码将是:
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')
另外,这部分:
if (socket.bind("tcp://*:5556"))
Print("Error");
else
Print("Bound");
应该反过来。当套接字成功绑定时,这实际上会打印一个错误。
【讨论】:
这是有道理的,但是即使这样,行为仍然保持不变。 您是否使用socket.setsockopt(zmq.SUBSCRIBE, b"")
而不是socket.setsockopt_string(zmq.SUBSCRIBE, '')
进行测试?
是的,我就是这么用的。 Python 端没有收到任何内容。
事实证明,我在 MQL 端对绑定的错误检查是错误的,所以当实际出现错误时它会打印“Bound”,反之亦然(当我看到它打印错误时,我是我猜想阻止它太快了)。 setsockopt_string
也可以。我将接受这一点,并对错误检查进行编辑 - 我希望你不介意。
另请注意,如果端口被其他东西使用,通常会出现错误 - 在我的情况下,5556 不起作用,但 5555 起作用。以上是关于Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字的主要内容,如果未能解决你的问题,请参考以下文章
ZMQ 套接字不是线程安全的,但我可以在不同的线程中使用 zmq_send() 和 zmq_recv() 吗?