Search code examples
javaclient-servermessage-queuezeromq

Is ZeroMQ server listening infinitely?


I am trying to implement client server using ZeroMQ.

I am running a server in an infinite loop, bound to a socket and polling the the socket infinitely.

When a client sends a request, the server receives only for the first time. The subsequent requests are not received by the server, below is my code snippet

Server :

        ZMQ.Socket socket = context.socket(ZMQ.REP);
        socket.bind ("tcp://*:5555");
        System.out.println("Server is in receive mode");
            while (!Thread.currentThread ().isInterrupted ()) {           
                Poller poller = new Poller(1);
                poller.register(socket, Poller.POLLIN);
                poller.poll();
                if (poller.pollin(0)) {
                    ZMsg zmqMessage = ZMsg.recvMsg(socket);                 
                    if (zmqMessage!=null) {
                        zmqMessage.getFirst().getData();
                    }
                }

Client :

    ZMQ.Socket socket = context.socket(ZMQ.REQ);
    socket.connect ("tcp://localhost:5555");
    ZMsg readyFrame = new ZMsg();
    readyFrame.add(new ZFrame("READY"));
    readyFrame.send(socket);

I tried poll out in client side like below but it did not work.

        Poller poller = new Poller(1);
        poller.register(socket, Poller.POLLOUT);
        poller.pollout(0);

Solution

  • ZeroMQ is a wonderfull piece of art from Pieter HINTJENS' and Martin SUSTRIK's team. Yes, there are some low-level, technology-related issues, that still require some design efforts, nevertheless the ZeroMQ is stable and very mature.

    System thinking - the toys are working as distributed automata

    Yes, normal work-flow of SEQ programming languages, that work serially ( or "just"-concurrent ) suddenly gets new dimension - a distributed automata dimension.

    So the local workflow is dependent on externally operated parties.

    This is the case for each of the ZeroMQ Formal Communication Patterns' primitive archetypes bear human-familiar names:

    one REQ-ests, second REP-lies
    one PUB-lishes, anyone SUB-scribes to just listen
    one PUSH-es, the other PULL-s to receive
    each party, bound together in PAIR may both speak and listen, whenever, as needed
    etc for BROKER, DEALER, XPUB, XSUB, et al

    This is the by-design reason, why your server-side REQ-archetype behaviour will not receive any next message from any other party ( yes, there might be more clients connected to the same REQ-transport-class node ), until it indeed REP-lies ( be it an empty message or not ) to the REP-side of the distributed automata.

    The best next step

    Well, the best next step one may ever do in going professional in this direction is IMHO to get a bit more global view, which may sound complicated for the first few things one tries to code with ZeroMQ, but if you at least jump to the page 265 of the [Code Connected, Volume 1] [available asPdf >>> http://hintjens.wdfiles.com/local--files/main%3Afiles/cc1pe.pdf ], if it were not the case of reading step-by-step thereto.

    The fastest-ever learning-curve would be to have first an un-exposed view on the Fig.60 Republishing Updates and Fig.62 HA Clone Server pair for a possible High-availability approach and then go back to the roots, elements and details.

    Overheads:

    As a minor note, it would be fair and resource-wise to lower the processing overheads once the Poller would be created "outside" the while(){}-loop, as there is no visible reason for reinstating such element and re-register it's services for each loop again and again:

    Poller poller      = new Poller(1);                  // new INSTANCE
    poller.register( socket, Poller.POLLIN );            // pay COSTS of SETUP
                                                         //     JUST ONCE, HERE
    while ( !Thread.currentThread ().isInterrupted () ) {// inf LOOP
    
        poller.poll();                                   //     POLL !BLOCKING
        if ( poller.pollin( 0 ) ) {                      //     if ITEMS{ ... proc 'em }
        ZMsg zmqMessage  = ZMsg.recvMsg( socket );
        if ( zmqMessage != null )
             zmqMessage.getFirst().getData();
        }
    }
    

    Anyway: Enjoy the worlds of distributed computing!