3

我在客户端有一个 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);
        });
    }
}
4

2 回答 2

2

你不应该使用 SendReady,它每次都会调用,因为路由器总是准备好发送。按照建议尝试阅读投票指南。另请阅读有关 NetMQScheduler 的信息,您可以使用它来代替 ConcurrentQueue。

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

于 2015-08-06T18:07:28.593 回答
0

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

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

尝试此链接以获取更多信息: NetMQ 指南 - 轮询

于 2015-08-06T06:21:24.900 回答