java - ZeroMQ: Disappearing messages -


we have java application acting server. client applications (written in c#) communicating using zeromq. (mostly) following lazy pirate pattern.

the server has router socket, implemented follows (using jeromq):

zcontext context = new zcontext(); socket socket = context.createsocket(zmq.router); socket.bind("tcp://*:5555"); 

the clients connect , send messages this:

zcontext context = zcontext.create(); zsocket socket = zsocket.create(context, zsockettype.req); socket.identity = encoding.utf8.getbytes("some identity"); socket.connect("tcp://my_host:5555"); socket.send(new zframe("request data")); 

we have experienced lost messages when multiple clients sending messages @ same time. single client, there doesn't appear problem.

are implementing right way multiple-client-single-server setup?

update: example client , server exhibiting behaviour:

server:

import org.zeromq.zcontext; import org.zeromq.zmq; import org.zeromq.zmq.pollitem; import org.zeromq.zmq.poller; import org.zeromq.zmq.socket; import org.zeromq.zmsg;  public class simpleserver {     public static void main(string[] args) throws interruptedexception     {         zcontext context = new zcontext();         socket socket = context.createsocket(zmq.router);         socket.setroutermandatory(true);         socket.bind("tcp://*:5559");          pollitem pollitem = new pollitem(socket, poller.pollin);          int messagesreceived = 0;         int pollcount = 0;          while ((pollcount = zmq.poll(new pollitem[]{pollitem}, 3000)) > -1)         {             messagesreceived += pollcount;              (int = 0 ; < pollcount ; i++)             {                 zmsg msg = zmsg.recvmsg(socket);                 system.out.println(string.format("received message: %s. total messages received: %d", msg, messagesreceived));             }              if (pollcount == 0)             {                 system.out.println(string.format("no messages on socket. total messages received: %d", messagesreceived));             }         }     } } 

client:

using netmq; using system; using system.text;  namespace simpleclient {     class program     {         static byte[] identity = encoding.utf8.getbytes("id" + datetime.utcnow.ticks);          static void main(string[] args)         {             (int = 0; < 100; i++)             {                 sendmessage();             }         }          private static void sendmessage()         {             using (netmqcontext context = netmqcontext.create())             {                 using (netmqsocket socket = context.createrequestsocket())                 {                     socket.options.identity = identity;                     socket.connect("tcp://localhost:5559");                     socket.send(encoding.utf8.getbytes("hello!"));                 }             }         }     } } 

if run server , single client, can see 100 messages arrive. if run, say, 5 clients simultaneously, around 200 -> 300 messages arrive, instead of full 500. aside, appears closing socket in client somehow stopping router socket on server receiving messages briefly, although theory.

part 1 - poll may return more 1 event

zmq.poll() returns number of events found:

int rc = zmq.poll(new pollitem[]{pollitem}, 3000); 

you assume 1 return poll 1 event. instead, should loop on zmsg msg = zmsg.recvmsg(socket); number of events indicated return of zmq.poll().

from source of jeromq:

/**  * polling on items. has poor performance.  * try use zmq_poll selector  * caution: affected jdk epoll bug  *  * @param items  * @param timeout  * @return number of events  */ public static int zmq_poll(pollitem[] items, long timeout) {     return zmq_poll(items, items.length, timeout); } 

part 2 - zmsg.receive() may return multiple frames

when receive zmsg zmsg msg = zmsg.recvmsg(socket);, zmsg may contain multiple zframes, each containing client data.

from comments of zmsg class in jeromq's source:

 * // receive message zmqsocket "input" socket object , iterate on frames  * zmsg receivedmessage = zmsg.recvmsg(input);  * (zframe f : receivedmessage) {  *     // frame f (of type zframe)  * } 

part 3 - messages can split across multiple zframes

from zframe's source in jeromq:

 * zframe class provides methods send , receive single message  * frames across 0mq sockets. 'frame' corresponds 1 underlying zmq_msg_t in libzmq code.  * when read frame socket, more() method indicates if frame part of  * unfinished multipart message. 

if i'm understanding correctly, each event may multiple frames, , 1 client message may map 1..n frames (if message big?).

so summarize:

  • one return poll may indicate multiple events.
  • one event , 1 zmsg.receive() may contain multiple frames
  • one frame contain 1 complete client message or part of client message; 1 client message maps 1..n frames.

Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

datatable - Matlab struct computations -