netmq icon indicating copy to clipboard operation
netmq copied to clipboard

Dealer / Router scalability issue

Open marian-gheorghe opened this issue 6 years ago • 4 comments

Environment

NetMQ Version:    4.0.0.239-pre
Operating System:  Linux / Windows
.NET Version:     NET Core 2.1

Expected behaviour

Hi I have a multi-client / single server scenario which I am modelling around Dealer / Router sockets. I am trying to connect 1000 clients to the server, but the server is able to accept the first 250-350.

Actual behaviour

The server is accepting 250-350 connection max.

Steps to reproduce the behaviour

Code for the client

NetMQClient.cs

    public class NetMQClient
    {
        DealerSocket client = new DealerSocket("tcp://127.0.0.1:25702");
        NetMQQueue<NetMQMessage> messageQueue = new NetMQQueue<NetMQMessage>();
        public NetMQClient ()
        {
            messageQueue.ReceiveReady += MessageQueue_ReceiveReady;
            client.Options.Backlog = 1000;
            client.ReceiveReady += Client_ReceiveReady;
        }

        private void Client_ReceiveReady(object sender, NetMQSocketEventArgs e)
        {
            while (e.Socket.TryReceiveFrameString(out string msg))
            {
                Console.WriteLine("REPLY From Server{0}", msg);
            }

        }

        public void StartSending(int id)
        {
            client.Options.Identity = Encoding.Unicode.GetBytes(id.ToString());
            var message = string.Format("Id = {0}", id.ToString());
            var bytes = Encoding.ASCII.GetBytes(message);


            using (var poller = new NetMQPoller())
            {
                poller.Add(client);
                poller.Add(messageQueue);
                poller.RunAsync();

                var messageToServer = new NetMQMessage();
                messageToServer.Append(message);
                messageQueue.Enqueue(messageToServer);
            }
        }

        private void MessageQueue_ReceiveReady(object sender, NetMQQueueEventArgs<NetMQMessage> e)
        {
            while (e.Queue.TryDequeue(out NetMQMessage messageToServer, TimeSpan.FromMilliseconds(10)))
            {
                client.SendMultipartMessage(messageToServer);
            }
        }
    }

Program.cs

    class Program
    {
        static void Main(string[] args)
        {
            Task.Factory.StartNew(() =>
            {
                for (var i = 1; i <= 1000; i++)
                {
                    var index = i;
                    Task.Factory.StartNew(() => new NetMQClient().StartSending(index));
                }
            });

            Console.WriteLine("Press any key to finish!");
            Console.ReadLine();
        }
    }

Code for the server

NetMQServer.cs

public class NetMQServer
    {
        static RouterSocket server;
        public void StartListening()
        {
            Console.WriteLine("Started and listening");
            server = new RouterSocket("@tcp://127.0.0.1:25702");
            server.Options.Backlog = 1000;
            server.ReceiveReady += Server_ReceiveReady;

            using (var poller = new NetMQPoller())
            {
                poller.Add(server);
                poller.RunAsync();
                Console.ReadLine();
            }
        }

        private void Server_ReceiveReady(object sender, NetMQSocketEventArgs e)
        {
            var fromClientMessage = new NetMQMessage();
            while (server.TryReceiveMultipartMessage(ref fromClientMessage))
            {
                var clientAddress = fromClientMessage[0];
                var clientOriginalMessage = fromClientMessage[1].ConvertToString();
                Console.WriteLine("From Client: {0}", clientOriginalMessage);

                var messageToClient = new NetMQMessage();
                messageToClient.Append(clientAddress);
                messageToClient.Append(clientOriginalMessage);
                e.Socket.SendMultipartMessage(messageToClient);
            }
        }
    }

Program.cs

    class Program
    {
        static void Main(string[] args)
        {
            var server = new NetMQServer();
            Task.Factory.StartNew(() => server.StartListening());
            Console.ReadLine();
        }
    }

Is there any way to achieve this or is anything wrong with the code above ? Thank you for your input.

marian-gheorghe avatar Nov 19 '19 13:11 marian-gheorghe

Any update to this? We're seeing the same issue.

jfjeschke avatar Apr 24 '20 19:04 jfjeschke

You can try Server/Client socket types instead of Router/Dealer. Seems that its using much less sockets and I'm able to create 1023 clients for 1 server, so 1024 in total. On Windows 10 OS

volmart avatar Apr 07 '21 06:04 volmart

This issue has been automatically marked as stale because it has not had activity for 365 days. It will be closed if no further activity occurs within 56 days. Thank you for your contributions.

stale[bot] avatar Apr 17 '22 03:04 stale[bot]