Python zmq SUB套接字未接收到MQL5 Zmq PUB套接字

时间:2018-11-29 22:33:20

标签: python python-3.x zeromq pyzmq mql5

我正在尝试在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调用将永远阻塞。因为可以看到打印件,所以在MT中触发了OnTick方法。

如何使它正常工作?

请注意,如果我切换到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 个答案:

答案 0 :(得分: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");

应该相反。成功绑定套接字后,这实际上会显示错误。