我如何使用cppzmq将ROUTER套接字的ZeroMQ消息发送到特定的DEALER套接字?

问题描述 投票:1回答:1

我整理了这个最小的示例,以便将消息从路由器套接字发送到特定的DEALER袜子(已设置了身份)。运行这两个程序时,它似乎挂在ROUTER上,等待来自DEALER的答复,而DEALER挂起,等待来自ROUTER的请求。因此,似乎[发送的消息永远不会传递给DEALER

Router.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(); }

Dealer.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);,但这会导致错误。同样使用以下内容也会导致错误:

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

据我所知,当使用cppzmq时,您不需要添加空的定界符(对此我可能是错的,但是在阅读并查看了其他人的示例并测试了我自己的代码之后,这就是我所确定的)。 

这是一个非常基本的图表,其最终目的是:

ROUTER to DEALER messaging design

在我的研究中,我找不到该代码的一个很好的例子。 Cppzmq github的文档很少,示例很少。

这里是我查看过的其他一些资料:

c++ sockets zeromq
1个回答
0
投票
阅读zeromq docs,我认为您缺少此部分(强调我的内容:]

阅读手册页时要注意的主要细节是要求用于在标识路由之间添加

空(空)消息部分所有邮件之前的信息以及包含以下内容的邮件正文应用程序级别的数据。 此空消息部分用作定界符将路由信息与应用程序级数据分开。

执行此操作:

socket.send(zmq::const_buffer{}, ZMQ_SNDMORE);

socket.send(ZMQ_NULLPTR, ZMQ_SNDMORE)

© www.soinside.com 2019 - 2024. All rights reserved.