zeromqjzmqreliable-multicast

Send and Receive data through same Socket in JZMQ


I am developing a JAVA multicast application using JZMQ (PGM protocol).

Is it possible to send and receive data through the same socket?

If ZMQ.PUB is used, only send() works and recv() is not working.

If ZMQ.SUB is used, send() doesn't work.

Is there any alternative way for using both send() and recv() using the same Socket?

ZMQ.Context context = ZMQ.context(1);
ZMQ.Socket socket = context.socket(ZMQ.PUB);
socket.send(msg);
socket.recv();

Solution

  • Radio broadcast will never deliver your voice into the Main Station

    Yes, both parts of the ZeroMQ PUB/SUB Scalable Formal Communication Pattern's archetypes are uni-directional ( by-definition ) one can just .send(), the other(s) may just listen ( and if were configured well, they will ).


    How to do what you have asked for? ( ... and forget to have this using pgm:// )

    Yes, there are ways to use other ZeroMQ archetypes for this - i.e. a single socket over PAIR/PAIR endpoints( capable of both .send() and .recv() methods ) or a pair of (A)->--PUSH/PULL->-(B) + (A)-<-PULL/PUSH-<-(B) so as to construct the bi-directional signalling / messaging channel by using just uni-directional archetypes.

    You also need to select an appropriate transport-class for being used in .bind() + .connect() between the configured ZeroMQ endpoints.

    // -------------------------------------------------------- HOST-(A)
       ZMQ.Context aCONTEXT   = ZMQ.context( 1 );
    
       ZMQ.Socket  aPubSOCKET = aCONTEXT.socket( ZMQ.PUB );
                   aPubSOCKET.setsockopt(        ZMQ.LINGER, 0 );
    // ----------------------
                   aPubSOCKET.bind( "tcp://*:8001" );
    // ----------------------
    // set msg = ...;
    // ----------------------
                   aPubSOCKET.send( msg, ZMQ.NOWAIT );
    
    // ...
    // ----------------------
                   aPubSOCKET.close();
                   aCONTEXT.term();
    // ----------------------
    

    The SUB-side has one more duty ...

    // -------------------------------------------------------- HOST-(B)
       ZMQ.Context aCONTEXT   = ZMQ.context( 1 );
    
       ZMQ.Socket  aSubSOCKET = aCONTEXT.socket( ZMQ.SUB );
                   aSubSOCKET.setsockopt(        ZMQ.LINGER,     0 );
                   aSubSOCKET.setsockopt(        ZMQ.SUBSCRIBE, "" );
    // ----------------------
                   aSubSOCKET.connect( "tcp://<host_A_IP_address>:8001" );
    // ----------------------
    // def a msg;
    // ----------------------
             msg = aSubSOCKET.recv( ZMQ.NOWAIT );
    
    // ...
    // ----------------------
                   aSubSOCKET.close();
                   aCONTEXT.term();
    // ----------------------