Search code examples
c#zeromqnetmq

What is the proper way to wait for connections?


I am trying to implement a simple message passing between two applications using NetMQ (a slightly more elaborate description of what I am trying to achieve is below).
After a bit of trial and error I've found that I can't just send or receive messages right away after a Connect/Bind calls, since they are non blocking and actually return even if the connection hasn't been established yet.
For now I solved this with Thread.Sleep(), but this has a bad taste to it and definitely a no-go for a production system.

So the question is, how's one supposed to do it in NetMQ/ZeroMQ?

Client example:

        using (NetMQContext ctx = NetMQContext.Create())
        {
            using (var client = ctx.CreatePushSocket())
            {
                client.Connect("tcp://127.0.0.1:5555");
                Thread.Sleep(100); // wait for connection

                for (int i = 0; i < 5; i++) 
                {
                    client.Send("test " + i , true);
                }
            }
        }
    }

Server example:

    using (NetMQContext ctx = NetMQContext.Create())
    {
        using (var server = ctx.CreatePullSocket())
        {
            server.Bind("tcp://127.0.0.1:5555");
            Thread.Sleep(100); // wait for connection
            while (true)
            {
                var str = server.ReceiveString();
                Console.Out.WriteLine(str);
                Thread.Sleep(60*1000); // do msg processing
            }
        }
    }

Description of what I am trying to achieve:

Client - Sends messages to a single server. The client should not block and should not discard messages when server is not available. The client can come offline/online at any time.

Server - Receives messages from a single client. The server blocks until a message is received. Server needs to do lengthy processing of the message and should not loose any other messages while processing. The server can come offline/online at any time.


Solution

  • The best solution to your sleep on the server side is to create a socket poller and poll on the pull socket until a message is received. This avoids wasteful sleeps, and makes for generally tighter code.

    On the client side the best solution is probably to create two sockets (one for sending messages, one for receiving), and have the server announce its presence ready for the client to send the message. Because ZeroMQ is efficient at handling multiple connections, this solution will work very well.