簡體   English   中英

如何使用 N 個生產者(連接)和 1 個消費者(綁定)構建一個普通的 zeroMQ 單向推拉模式 - MT4 到 Python

[英]How to structure a plain zeroMQ one way Push-Pull pattern with N-producers (connect) and 1-consumer (bind) - MT4 to Python

多個用戶將數據從 Metatrader 4 推送到 Python 后端。 因此 Metatrader 4(=生產者)的運行實例數量是動態的。 每個 MT4 實例都將在用戶本地機器上運行,創建自己的 zmq.context 和 zmq.socket(推送)。 所以我們最終得到了一個 N 對 1 的結構:

|--------------------生產者1-----生產者2-----生產者3-----生產者4-----生產者X ---- ---------------------------------------------|---- ---------------|----------------|---------------- |--------------------|----------------------------- ——
......................................|--------- --------消費者/后端-----------|.......... ……………………

話雖如此,消費者將 24/7 全天候運行並等待來自任何生產者的數據。例如,如果有 160 個用戶在線使用該服務,消費者將不得不處理從這 160 個節點輸入的數據,依此類推。 接收消息的順序無關緊要,如果某些消息偶爾掉線,也無關緊要。

在此處輸入圖片說明

當前狀態:
現在我的代碼(見下文)在我自己的本地機器上使用一個 Metatrader 4 實例運行得非常好。 但是,如果有X個 MT4 實例並且它們都有自己的 zmq 上下文並在本地元交易者 4 實例中推送套接字以發送數據,會發生什么情況? 它也會按預期工作嗎?

代碼生產者端(Metatrader 4 實例),每個用戶都將在他的本地機器上運行:

extern string ZEROMQ_PROTOCOL = "tcp";
extern string HOSTNAME = "localhost";
extern int PUSH_PORT = 32225;

// CREATE ZeroMQ Context
Context context(PROJECT_NAME);

// CREATE ZMQ_PUSH SOCKET
Socket pushSocket(context, ZMQ_PUSH);

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

int OnInit()
  {

//---

   EventSetTimer(1);     // Set Second Timer as push intervall

   context.setBlocky(false);

   // Send data to PULL_PORT that consumer is listening to.
   Print("[PUSH] Connecting MT4 Dashex Feeder to Dashboard on Port " + IntegerToString(PUSH_PORT) + "..");
   pushSocket.connect(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));

   pushSocket.setSendHighWaterMark(1);
   pushSocket.setLinger(0);   

   return(INIT_SUCCEEDED);
  }

//---

void OnDeinit(const int reason)
{

//---

   Print("[PUSH] Disconnecting MT4 Dashex Feeder on Port " + IntegerToString(PUSH_PORT) + "..");
   pushSocket.disconnect(StringFormat("%s://%s:%d", ZEROMQ_PROTOCOL, HOSTNAME, PUSH_PORT));

   // Shutdown ZeroMQ Context
   context.shutdown();
   context.destroy(0);

   EventKillTimer();
}

[...]

pushSocket.send(StringFormat("%s", account_info, true));

Python后端消費者:

# create zeroMQ Pull Socket to fetch data out of the wire
context = zmq.Context()
zmq_socket = context.socket(zmq.PULL)
zmq_socket.bind("tcp://*:32225")
time.sleep(1)

while True:
    # check 24/7 for available data in the pull socket
    try:
        [...]

問題:

1.)當前代碼為在用戶本地機器上運行的每個 Metatrader 4 實例創建一個新的上下文和套接字,並在 MT4 關閉后再次關閉它們。 多個 MT4 實例/推送套接字可以一次向同一個消費者發送數據嗎? (這是我想要的結果)

2.)另外,每個終端實例可以使用相同的套接字端口還是每個終端實例都需要一個唯一的端口?

3.)我應該使用不同的模式嗎?

在此先非常感謝您的想法和意見。

  1. 如果您使用inproc傳輸,則只需要共享上下文。 當您使用tcp它會按您的預期工作。
  2. 終端將connect()與 python 后端bind()指定的端口。 所以是的,所有終端都將連接到代碼中指定的端口 32225。
  3. 推/拉模式似乎是一個不錯的選擇,應該可以正常工作。 如果您擔心 python 后端的開銷(許多連接),您可以在終端和后端之間放置一個 zeromq 代理(PULL/PUSH)代理進程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM