Does ZeroMQ have a notification/callback event/message for when data arrives?

前端 未结 3 2060
难免孤独
难免孤独 2020-12-19 18:42

I am trying to integrate ZMQ into an existing windows application that relies heavily on MFC sockets (CASyncSocket).

I\'ve got a CWinThread derived UI thread (with

3条回答
  •  长情又很酷
    2020-12-19 19:29

    Ultimately, the answer is no. There are no current callback/notifications for when data arrives in ZeroMQ that you can link into. I was also unable to find any fork that adds this functionality.

    I was unable to get ZMQ working while using the traditional OnReceive calls provide by the MFC socket framework within a single thread and adding a 2nd thread to dedicate to ZMQ defeated the whole purpose for using it (it is being used for thread synchronization).

    My implementation that works ended up dropping MFC sockets and using ZMQ for both my inproc server (for communicating with other thread) as well as my TCP (non-ZMQ) server connection and using a blocking polling call (zmq_poll()) in the OnIdle() method (returning 1 every time to create a busy loop). The blocking poll

    BOOL CMyThreaClass::OnIdle(LONG lCount)
    {
        UNREFERENCED_PARAMETER(lCount);
    
        zmq_pollitem_t items [] = {
        { m_pZMQInprocServer, 0, ZMQ_POLLIN, 0 },
        { m_pZMQTCPSocket, 0, ZMQ_POLLIN, 0 }
        };
        const int iZMQInfiniteTimeout(-1);
        iResult = zmq_poll(&items[0], sizeof(items) / sizeof(items[0]), iZMQInfiniteTimeout);
        TRACE("zmq_poll result: %d\n", iResult);
    
        if (items[0].revents & ZMQ_POLLIN)
        {
            sMyStruct sMessage;
            iResult = zmq_recv(m_pZMQInprocServer, &sMessage, sizeof(sMessage), ZMQ_DONTWAIT); // don't block (the zmq_poll blocks for us)
            TRACE("inproc recv result: %d\n", iResult);
            //  Process inproc messages
            iResult = zmq_send(pZMQInprocServer, &sMessage, sizeof(sMessage), ZMQ_NULL); // block
            TRACE("inproc send result: %d\n", iResult);
        }
        if (items[1].revents & ZMQ_POLLIN)
        {
            // there will be an ZMQ_IDENTITY identifier on the beginning of the socket buffer, read it off first
            uint8_t id [256];
            size_t id_size = 256;
            iResult = zmq_getsockopt(m_pZMQTCPSocket, ZMQ_IDENTITY, id, &id_size);
            TRACE("getsockopt poll result %d:id %d\n", iResult, id);
            iResult = zmq_recv(m_pZMQTCPSocket, &id, id_Size, ZMQ_DONTWAIT); // don't block
            // now get our actual data
            char szBuffer[1024];
            int iBytesReceived = zmq_recv(m_pZMQSocket, szBuffer, sizeof(szBuffer), ZMQ_DONTWAIT);
            if (iBytesReceived > 0)
            {
                // process TCP data
            }
        }
    }
    

    Note: This answer requires using ZMQ 4 or later since earlier versions of ZMQ will not communicate with a regular TCP socket connection.

提交回复
热议问题