NetMQ中的RouterSocket上的轮询器

时间:2015-08-04 11:22:28

标签: c# .net zeromq netmq

我在客户端有一个RequestSocket向服务器发送请求。服务器必须能够并行处理请求,所以我使用了带轮询器的RouterSocket。

我不确定这是否是最好的实现,因为它在没有请求处理的情况下使用了相当数量的CPU?特别是RouterSocket上的SendReady事件经常被触发。

class Program
{
    static ConcurrentQueue<NetMQMessage> outgoingQueue = new ConcurrentQueue<NetMQMessage>();

    static void Main(string[] args)
    {
        var poller = new Poller();
        using (var context = NetMQContext.Create())
        using (var router = context.CreateRouterSocket())
        {
            router.Bind("tcp://127.0.0.1:1337");
            poller.AddSocket(router);

            router.ReceiveReady += (s, a) => HandleRequest(a.Socket.ReceiveMessage());

            router.SendReady += (s, a) =>
            {

                if (!outgoingQueue.IsEmpty)
                {
                    NetMQMessage msg;
                    if (outgoingQueue.TryDequeue(out msg))
                    {
                        a.Socket.SendMessage(msg);
                        Console.WriteLine("Sent: " + msg[2].ConvertToString());
                    }
                }
            };
            poller.Start();
        }
    }

    static void HandleRequest(NetMQMessage requestMsg)
    {
        Console.WriteLine("Received: " + requestMsg[2].ConvertToString());
        Task.Factory.StartNew(() =>
        {
            Thread.Sleep(1000);
            NetMQMessage responseMsg = new NetMQMessage();
            responseMsg.Append(requestMsg[0]);
            responseMsg.AppendEmptyFrame();
            responseMsg.Append("Enjoy " + requestMsg[2].ConvertToString());
            outgoingQueue.Enqueue(responseMsg);
        });
    }
}

2 个答案:

答案 0 :(得分:2)

您不应该使用SendReady,因为路由器随时可以发送,所以每次都会调用它。如建议尝试阅读投票指南。另请阅读NetMQScheduler,您可以使用它而不是ConcurrentQueue。

http://somdoron.com/2013/06/netmq-scheduler/

答案 1 :(得分:0)

可以向正在轮询的套接字添加计时器,以控制轮询的频率,如netMQ指南所指定:

  

如果您希望定期执行某些操作,并且需要在允许使用一个或多个套接字的线程上执行该操作,则可以将PolMQTimer与您要使用的套接字一起添加到Poller。 / p>

尝试此链接以获取更多信息: NetMQ guide - Polling