在收到请求期间,ZeroMQ REP套接字被阻止

时间:2019-01-24 09:18:39

标签: sockets request synchronization response zeromq

我正在尝试使用REQ / REP套接字同步我的PUB / SUB套接字。这在大多数时间都是有效的,但是有时在接收方法期间REP套接字被阻塞。我对PUB / REP和SUB / REQ使用相同的ZMQ上下文。因此,对于同步,我的订户正在向发布者发送请求。然后,发布者发回了答复。如果发布者收到了所有预期订阅者的请求,则同步完成。

发布者

Publisher::Publisher(zmq::context_t & ctx) :
    mZMQcontext(ctx), mZMQpublisher(mZMQcontext, ZMQ_PUB), mZMQSyncService(
            mZMQcontext, ZMQ_REP) 
{
    mZMQpublisher.setsockopt(ZMQ_LINGER, 100);
}

void Publisher::bindSocket(std::string port) 
{
    mZMQpublisher.bind("tcp://*:" + port);
}

void Publisher::preparePubSynchronization(std::string port) 
{
    mZMQSyncService.bind("tcp://*:" + port);
}

void Publisher::synchronizePub(uint64_t expectedSubscribers) 
{
    //  Synchronization with subscribers
    uint64_t subscribers = 0;

    while (subscribers < expectedSubscribers) 
    {
         // >>>>> Is randomely blocked here <<<<<
         std::string request = s_recv(mZMQSyncService);
         s_send(mZMQSyncService, request);
         subscribers++;
    }
}

订户

Subscriber::Subscriber(zmq::context_t & ctx) :
    mZMQcontext(ctx), mZMQsubscriber(mZMQcontext, ZMQ_SUB)
{
     mZMQsubscriber.setsockopt(ZMQ_LINGER, 100);
}

bool Subscriber::connectToPub(std::string ip, std::string port)
{
     mZMQsubscriber.connect("tcp://" + ip + ":" + port);
}

bool Subscriber::prepareSubSynchronization(std::string ip, std::string port) 
{
    mSyncIP = ip;
    mSyncPort = port;
}

// Helper function to get a new socket
zmq::socket_t* Subscriber::newSyncSocket() 
{
    zmq::socket_t* client = new zmq::socket_t(mZMQcontext, ZMQ_REQ);
    client->connect("tcp://" + mSyncIP + ":" + mSyncPort);
    client->setsockopt(ZMQ_LINGER, 0);
    return client;
}

bool Subscriber::synchronizeSub() 
{
    zmq::socket_t* client = newSyncSocket();

    int retries_left = 3;
    std::string request = mOwner;
    s_send(*client, request );

    bool expect_reply = true;
    while (expect_reply) 
    {
         //  Poll socket for a reply, with timeout
         zmq::pollitem_t items[] = { { *client, 0, ZMQ_POLLIN, 0 } };
         zmq::poll(&items[0], 1, REQUEST_TIMEOUT);

         //  If we got a reply, process it
         if (items[0].revents & ZMQ_POLLIN) 
         {
              //  We got a reply from the publisher -> must match request
              std::string reply = s_recv(*client);

              if (reply == request) 
              {
                   // Valid reply
                   expect_reply = false;
              } 

         } else if (--retries_left == 0) 
         {
              // publisher seems to be offline, abandoning
              delete client;
              return false;
         } else 
         {
              // No response from publisher, retrying ...
              // Old socket will be confused; close it and open a new one
              delete client;
              client = newSyncSocket();
              // Send request again, on new socket
              s_send(*client, request);
         }
}
    delete client;
    return true;
}

0 个答案:

没有答案