我正在尝试使用NetMQ在两个应用程序之间传递一个简单的消息(稍微详细说明我想要实现的内容如下)。
经过一些试验和错误后,我发现在Connect / Bind调用之后我不能立即发送或接收消息,因为它们是非阻塞的,即使尚未建立连接也会实际返回。登记/>
现在我用Thread.Sleep()解决了这个问题,但这对它有不好的品味,对于生产系统来说绝对不行。
所以问题是,如何在NetMQ / ZeroMQ中做到这一点?
客户端示例:
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);
}
}
}
}
服务器示例:
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
}
}
}
我想要实现的目标的描述:
客户端 - 将消息发送到单个服务器。当服务器不可用时,客户端不应阻止并且不应丢弃消息。客户端可以随时离线/在线。
服务器 - 从单个客户端接收消息。服务器将阻塞,直到收到消息。服务器需要对消息进行冗长的处理,并且在处理时不应丢失任何其他消息。服务器可以随时离线/在线。
答案 0 :(得分:9)
接收和发送都可以等到可以执行,你在你的例子中将true传递给dontWait参数,只需删除它就会在可能的时候发送消息。
对于接收,您不必睡觉,因为它会等到消息可用。
正如建议使用Poller也是一个解决方案(您可以轮询套接字何时可以发送以及消息何时可以使用),请查看poller类的测试:https://github.com/zeromq/netmq/blob/3.3.3-rc5/src/NetMQ.Tests/PollerTests.cs。
答案 1 :(得分:5)
在服务器端睡眠的最佳解决方案是在拉出套接字上创建套接字轮询器并轮询,直到收到消息。这避免了浪费的睡眠,并且通常会使代码更加严密。
在客户端,最好的解决方案可能是创建两个套接字(一个用于发送消息,一个用于接收),并让服务器宣布其存在,以便客户端发送消息。由于ZeroMQ在处理多个连接方面非常有效,因此该解决方案可以很好地工作。