簡體   English   中英

如何使用 cppzmq 從 ROUTER 套接字向特定的 DEALER 套接字發送 ZeroMQ 消息?

[英]How can I send a ZeroMQ message from a ROUTER socket to a specific DEALER socket using cppzmq?

我把這個最小的例子放在一起,以便將消息從路由器套接字發送到特定的DEALER socker(它有它的身份集)。 當運行這兩個程序時,它似乎掛在ROUTER 上等待來自DEALER的回復,而DEALER掛起等待來自ROUTER的請求。 因此,似乎ROUTER發送的消息從未發送到DEALER

路由器.cpp

#include <iostream>
#include <zmq.hpp>
#include <string>
#include <thread>
#include <chrono>

int main() {
    zmq::context_t context;
    zmq::socket_t socket (context, zmq::socket_type::router);
    // Enforce sending routable messages only
    socket.setsockopt(ZMQ_ROUTER_MANDATORY, 1);
    socket.bind("tcp://*:5555");

    try {
        std::string jobRequest = "ExampleJobRequest";

        std::cout << "Router: Sending msg: " << jobRequest << std::endl;

        // Set the address, then the empty delimiter and then the request itself
        socket.send("PEER2", ZMQ_SNDMORE);
        //socket.send(zmq::message_t(), ZMQ_SNDMORE);
        socket.send(zmq::str_buffer("ExampleJobRequest")) ;

        // Set the address, then the empty delimiter and then the request itself
        socket.send("PEER2", ZMQ_SNDMORE);
        //socket.send(zmq::message_t(), ZMQ_SNDMORE);
        socket.send(zmq::str_buffer("ExampleJobRequest")) ;

        // Receive the reply from the camera
        std::cout << "Router: Waiting for reply from camera " << std::endl;
        zmq::message_t reply;
        socket.recv(&reply);

        std::cout << "Router: Received " <<  std::string(static_cast<char*>(reply.data()), reply.size()) << std::endl;
    } catch (std::exception e) {
        std::cout << "Router Error: " << e.what();
    }

    std::this_thread::sleep_for(std::chrono::seconds(1));
    socket.close();
    context.close();
}

經銷商.cpp

#include <zmq.hpp>
#include <string>
#include <iostream>
#include <thread>

int main (void)
{
    //  Prepare our context and socket
    zmq::context_t context;
    zmq::socket_t socket (context, zmq::socket_type::dealer);

    std::cout << "Dealer: Connecting to RunJob server… \n";
    socket.setsockopt(ZMQ_IDENTITY, "PEER2", 5);
    socket.connect ("tcp://localhost:5555");

    while(true) {
        try {
            // Wait for next request from client
            std::cout << "Dealer: Waiting for request" << std::endl;
            zmq::message_t request;
            zmq::message_t empty;

            // Receive request
            socket.recv(&request);

            std::string requestString = std::string(static_cast<char*>(request.data()), request.size());

            std::cout << "Dealer: Received request" << std::endl;
            std::cout << requestString << std::endl;

            // ZMQ_SNDMORE - "Specifies that the message being sent is a multi-part message, and that further message parts are to follow"
            socket.send(zmq::str_buffer("Job completed"), zmq::send_flags::dontwait);
        }catch (std::exception e) {
            std::cout << "Router Error: " << e.what();
        }
    }

    // Used to set various 0MQ Socket Settings
    // ZMQ_Linger - Set linger period for socket shutdown
    socket.setsockopt(ZMQ_LINGER, 0);
    socket.close();
    context.close();

    return 0;
}

我最初認為我應該在消息前面加上一個空分隔符socket.send(zmq::message_t(), ZMQ_SNDMORE); ,但這導致了錯誤。 同樣使用以下內容也會導致在 try/catch 塊中拋出錯誤。 該錯誤只是打印“未知錯誤”:

zmq::message_t delimiter(0);
socket.send(delimiter, ZMQ_SNDMORE);

使用以下內容創建分隔符也會導致相同的錯誤:

socket.send(zmq::message_t(), ZMQ_SNDMORE);

據我所知,在使用 cppzmq 時,您不需要添加空分隔符(我可能錯了,但在閱讀並查看其他人的示例並測試我自己的代碼后,這是我確定的)。

這是一個非常基本的圖表,其中包含此設計的最終目標:

路由器到經銷商的消息傳遞設計

在我的研究中,我沒有找到這段代碼的好例子。 Cppzmq github 的文檔和示例很少。

以下是我看過的其他一些來源:

ROUTER/DEALER 模式的主要思想是它是 REPLY/REQUEST 的異步泛化。 然而,您正在嘗試反轉模式中的套接字,發現它不適合並扭曲代碼以嘗試使其適合。 不要那樣做。

你需要做的是“順其自然”。 在存在示例的簡單方法中,DEALER 應發送第一條消息。 然后路由器對此做出響應。

下一級別是讓 DEALER 在其啟動消息中標識自己。 ROUTER 然后可以給那個 DEALER 一個特定的響應。

在下一個級別,您可以真正實現異步。 ROUTER 可以獲取每個 DEALER 的標識消息的副本,並使用消息副本隨時向任何 DEALER 發送異步消息。 標識消息的一份副本將附加“PEER2”幀並發送給經銷商。 這是有效的,因為消息的副本包括路由幀。 理想情況下,您還可以刪除“消息”幀,只在副本中保留路由幀。

警告 - 我不使用 cppzmq,我使用 CZMQ。 我可以說使用 CZMQ 這種幀操作非常容易。

暫無
暫無

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

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