ZeroMQ(clrzmq4)民意调查问题

时间:2016-08-06 03:23:58

标签: zeromq

我想要实现的是实现从两个套接字中的一个读取消息,无论它到达何处。据我所知,民意调查(zmq_poll)是正确的事情(如mspoller in guide所示)。在这里,我将提供小的伪代码片段:

TimeSpan timeout = TimeSpan.FromMilliseconds(50);

using (var receiver1 = new ZSocket(ZContext.Current, ZSocketType.DEALER))
using (var receiver2 = new ZSocket(ZContext.Current, ZSocketType.PAIR))
{
    receiver1.Bind("tcp://someaddress");
    // Note that PAIR socket is inproc:
    receiver2.Connect("inproc://otheraddress");

    var poll = ZPollItem.CreateReceiver();

    ZError error;
    ZMessage msg;

    while (true)
    {
        if (receiver1.PollIn(poll, out msg, out error, timeout))
        {
            // ...
        }

        if (receiver2.PollIn(poll, out msg, out error, timeout))
        {
            // ...
        }
    }
}

正如您所看到的,它实际上与mspoller in guide中的实现完全相同。

在我的情况下,receiver2(PAIR套接字)应该收到大量消息。事实上,我已经创建了一个测试,其中发送给它的消息数总是大于它能够接收的消息数(至少在演示的实现中)。

我已经进行了2秒的测试,我对结果感到非常惊讶:

  • 发送到receiver2的邮件数量:180(“已发送”是指它们分发给上一个代码段中未显示的另一个PAIR套接字);
  • receiver2收到的邮件数量:21 ??? 2秒内只有21条消息???每秒10条消息???

然后我尝试使用不同的timeout值,我发现它会显着影响收到的消息数量。持续时间(2秒)和发送的消息数(180)保持不变。结果是:

  • timeout值200毫秒 - 收到的邮件数量下降到10(每秒5个);
  • timeout值为10毫秒 - 收到的消息数量增加到120(每秒60个)。

结果告诉我,投票根本不起作用。如果轮询工作正常,据我了解机制,timeout在这种情况下不应该有任何影响。无论我们将超时设置为1小时还是5毫秒 - 因为总有消息要接收,所以没有什么可以等待,所以循环应该使用相同的速度

我的另一个重要问题是,即使timeout值非常小receiver2,也无法接收所有180条消息。我在这里努力实现每秒100条消息的接收速率,虽然我选择了ZeroMQ,它应该非常快(基准测试提到数字为每秒600万条消息)。

所以我的问题显而易见:我在这里做错了吗?有没有更好的方法来实施民意调查?

通过浏览clrzmq4代码,我注意到也可以在枚举套接字ZPollItems.cs, line 151时调用pollIn方法,但我没有在任何地方找到任何示例!

这可能是正确的做法吗?任何文件都在哪里?

由于

1 个答案:

答案 0 :(得分:3)

我发现了问题/解决方案。而是分别在每个套接字上使用PollIn方法,我们应该在套接字数组上使用PollIn方法。显然the example from the guide HUGELY MISLEADING 。这是正确的方法:

TimeSpan timeout = TimeSpan.FromMilliseconds(50);

using (var receiver1 = new ZSocket(ZContext.Current, ZSocketType.DEALER))
using (var receiver2 = new ZSocket(ZContext.Current, ZSocketType.PAIR))
{
    receiver1.Bind("tcp://someaddress");
    receiver2.Connect("inproc://otheraddress");

    // We should "remember" the order of sockets within the array
    // because order of messages in the received array will correspond to it.
    ZSocket[] sockets = { receiver1, receiver2 };

    // Note that we should use two ZPollItem instances:
    ZPollItem[] pollItems = { ZPollItem.CreateReceiver(), ZPollItem.CreateReceiver() };

    ZError error;
    ZMessage[] msg;

    while (true)
    {
        if (sockets.PollIn(pollItems, out msg, out error, timeout))
        {
            if (msg[0] != null)
            {
                // The first message gotten from receiver1
            }

            if (msg[1] != null)
            {
                // The second message gotten from receiver2
            }
        }
    }
}

现在receiver2每秒收到15,000条收到的邮件,无论timeout值是多少,也不论receiver1收到的邮件数量是多少。

更新:来自clrzmq4的人已经确认this issue,所以可能很快就会更正这个例子。