I have a follow-up to How to implement Pub-Sub Network with a Proxy by using XPUB and XSUB in ZeroMQ(C++)?
That question requested a C++ proxy using XSUB and XPUB. The answer given is essentially the proxy main() function quoted below.
I extended this proxy to a full working example including a publisher and subscriber. The catch is that my code only works with dealer / router options (as shown in comments below). With the actual (uncommented) XPUB / XSUB options below, subscribers don't get messages. What's going wrong? Is there a tweak to get messages to arrive?
Proxy not working with XPUB/XSUB (working dealer / router in comments)
#include <zmq.hpp>
int main(int argc, char* argv[]) {
zmq::context_t ctx(1);
zmq::socket_t frontend(ctx, /*ZMQ_ROUTER*/ ZMQ_XSUB);
zmq::socket_t backend(ctx, /*ZMQ_DEALER*/ ZMQ_XPUB);
frontend.bind("tcp://*:5570");
backend.bind("tcp://*:5571");
zmq::proxy(frontend, backend, nullptr);
return 0;
}
Subscriber not working with ZMQ_SUB (working dealer / router option in comments)
#include <iostream>
#include <zmq.hpp>
std::string GetStringFromMessage(const zmq::message_t& msg) {
char* tmp = new char[msg.size()+1];
memcpy(tmp,msg.data(),msg.size());
tmp[msg.size()] = '\0';
std::string rval(tmp);
delete[] tmp;
return rval;
}
int main(int argc, char* argv[]) {
zmq::context_t ctx(1);
zmq::socket_t socket(ctx, /*ZMQ_DEALER*/ ZMQ_SUB);
socket.connect("tcp://localhost:5571");
while (true) {
zmq::message_t identity;
zmq::message_t message;
socket.recv(&identity);
socket.recv(&message);
std::string identityStr(GetStringFromMessage(identity));
std::string messageStr(GetStringFromMessage(message));
std::cout << "Identity: " << identityStr << std::endl;
std::cout << "Message: " << messageStr << std::endl;
}
}
Publisher not working with ZMQ_PUB (working dealer / router option in comments)
#include <unistd.h>
#include <sstream>
#include <zmq.hpp>
int main (int argc, char* argv[])
{
// Context
zmq::context_t ctx(1);
// Create a socket and set its identity attribute
zmq::socket_t socket(ctx, /*ZMQ_DEALER*/ ZMQ_PUB);
char identity[10] = {};
sprintf(identity, "%d", getpid());
socket.setsockopt(ZMQ_IDENTITY, identity, strlen(identity));
socket.connect("tcp://localhost:5570");
// Send some messages
unsigned int counter = 0;
while (true) {
std::ostringstream ss;
ss << "Message #" << counter << " from PID " << getpid();
socket.send(ss.str().c_str(),ss.str().length());
counter++;
sleep(1);
}
return 0;
}