jeudi 12 décembre 2019

ZMQ Xpub/Xsub not sending subscription messages

I am experimenting with ZMQ using a XPUB/XSUB proxy. ultimately I want to insert some logic in the middle so I attempted to build my own proxy with zmq_poll instead of using the built in zmq_proxy. however my xpub never receives any subscription messages to forward. the code below works (subscriber prints hellowWorld) if I use the built in proxy. It does not work with my custom proxy. I've tried setting the very verbose/manual socket options and adding delays but can't seem to make it work.

void proxyBuiltIn(zmq::context_t* context)
{
    zmq::socket_t frontend(*context, ZMQ_XSUB);
    zmq::socket_t backend(*context, ZMQ_XPUB);
    frontend.bind("inproc://frontend");
    backend.bind("inproc://backend");
    zmq::proxy(frontend, backend);
 }

 void proxyCustom(zmq::context_t* context)
 {
     zmq::socket_t frontend(*context, ZMQ_XSUB);
     zmq::socket_t backend(*context, ZMQ_XPUB);
     frontend.bind("inproc://frontend");
     backend.bind("inproc://backend");

     zmq::pollitem_t items[2] =
     {
         { frontend, 0, ZMQ_POLLIN, 0 },
         { backend, 0, ZMQ_POLLIN, 0 },
     };

     while (1)
     {
         if (zmq::poll(items, 1, 1000) == -1){ break;}
         if (items[0].revents & ZMQ_POLLIN)
         {
             std::cout << "got published message" << std::endl; // won't get here because subscription is not made
             zmq::multipart_t message;
             message.recv(frontend);
             message.send(backend);
         }

         if (items[1].revents & ZMQ_POLLIN)
         {
             std::cout << "got subscription message" << std::endl; // never gets here.
             zmq::multipart_t message;
             message.recv(backend);
             message.send(frontend);
         }
     }
 }

 void subscriber(zmq::context_t* context)
 {
     zmq::socket_t subscriber(*context, ZMQ_SUB);
     subscriber.connect("inproc://backend");
     std::string topic = "testTopic";
     subscriber.setsockopt(ZMQ_SUBSCRIBE, topic.c_str(), topic.size());

     while (1)
     {
         zmq::multipart_t incoming;
         incoming.recv(subscriber);

         std::string topic = incoming.popstr();
         std::string data = incoming.popstr();
         std::cout << topic.c_str() << ", " << data.c_str() << std::endl;
     }
 }

 void publisher(zmq::context_t* context)
 {
     zmq::socket_t publisher(*context, ZMQ_PUB);
     publisher.connect("inproc://frontend");

     while (1)
     {
         zmq::multipart_t message;
         message.addstr("testTopic");
         message.addstr("helloWorld!");
         message.send(publisher);
         std::this_thread::sleep_for(std::chrono::milliseconds(1000));
     }
 }

 int main(int argc, char **argv)
 {
     zmq::context_t* context = new zmq::context_t(1);
     std::thread(proxyCustom, context).detach(); //this does not
     //std::thread(proxyBuiltIn, context).detach(); //this works
     std::thread(publisher, context).detach();
     std::thread(subscriber, context).detach();
     while(1)
     {

     }

 }

Aucun commentaire:

Enregistrer un commentaire