bool OTSocket_ZMQ_2::Receive(OTString & strServerReply) { if (!m_bInitialized) { OT_FAIL; } if (!m_HasContext) { OT_FAIL; } if (NULL == m_pzmq->context_zmq) { OTLog::vError("%s: Error: %s must exist to Receive!\n", __FUNCTION__, "m_pzmq->context_zmq"); OT_FAIL; } if (!m_bConnected && !m_bListening) return false; if (m_bConnected && m_bListening) return false; if (NULL == m_pzmq->socket_zmq) { OTLog::vError("%s: Error: %s must exist to Receive!\n", __FUNCTION__, "m_pzmq->socket_zmq"); OT_FAIL; } // ----------------------------------- const long lLatencyRecvMilliSec = m_lLatencyReceiveMs; const long lLatencyRecvMicroSec = lLatencyRecvMilliSec * 1000; // *********************************** // Get the reply. zmq::message_t zmq_message; bool bSuccessReceiving = false; // If failure receiving, re-tries 2 times, with 4000 ms max delay between each (Doubling every time.) // if (m_bIsBlocking) { bSuccessReceiving = m_pzmq->socket_zmq->recv(&zmq_message); // Blocking. } else // not blocking { long lDoubling = lLatencyRecvMicroSec; int nReceiveTries = m_nLatencyReceiveNoTries; bool expect_reply = true; while (expect_reply) { // Poll socket for a reply, with timeout zmq::pollitem_t items[] = { { *m_pzmq->socket_zmq, 0, ZMQ_POLLIN, 0 } }; const int nPoll = zmq::poll(&items[0], 1, lDoubling); lDoubling *= 2; // If we got a reply, process it if (items[0].revents & ZMQ_POLLIN) { bSuccessReceiving = m_pzmq->socket_zmq->recv(&zmq_message, ZMQ_NOBLOCK); // <=========== RECEIVE =============== OTLog::SleepMilliseconds(1); if (!bSuccessReceiving) { if (false == HandleReceivingError()) expect_reply = false; } else break; // (Success -- we're done in this loop.) } else if (nReceiveTries == 0) { //OTLog::Error("OTSocket::Receive: no message.\n"); expect_reply = false; break; } else if ((-1) == nPoll) // error. { if (false == HandlePollingError()) expect_reply = false; } --nReceiveTries; } } // *********************************** if (bSuccessReceiving && (zmq_message.size() > 0)) strServerReply.MemSet(static_cast<const char*>(zmq_message.data()), static_cast<uint32_t> (zmq_message.size())); return (bSuccessReceiving && (zmq_message.size() > 0)); }