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.
both receive and send can wait until can be executed, you passed true to dontWait parameter on your example, just remove it and it will send the message when it can.
For the receive you don't have to sleep because it will wait until message is available.
As suggested using Poller is also a solution (you can poll when the socket can send and when messages are ready to be consumed), take a look at the testing for poller class: https://github.com/zeromq/netmq/blob/3.3.3-rc5/src/NetMQ.Tests/PollerTests.cs.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With