예제 #1
0
        public void Send_NoServiceNameWithLogging_ShouldThrowApplicationException()
        {
            const string hostAddress     = "tcp://localhost:5555";
            var          loggingMessages = new List <string>();

            // setup the counter socket for communication
            using (var session = new MDPClient(hostAddress))
            {
                // set the event handler to receive the logging messages
                session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info);
                // well formed message
                var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });
                // correct call
                try
                {
                    session.Send(string.Empty, requestMessage);
                }
                catch (ApplicationException ex)
                {
                    Assert.That(ex.Message, Is.EqualTo("serviceName must not be empty or null."));
                }

                Assert.That(loggingMessages.Count, Is.EqualTo(0));
            }
        }
예제 #2
0
        public void Send_WrongServiceNameWithLogging_ShouldLogPermanentError()
        {
            const string hostAddress     = "tcp://localhost:5555";
            var          loggingMessages = new List <string>();

            // setup the counter socket for communication
            using (var broker = new RouterSocket())
                using (var poller = new NetMQPoller())
                    using (var session = new MDPClient(hostAddress))
                    {
                        broker.Bind(hostAddress);
                        // we need to pick up any message in order to avoid errors
                        broker.ReceiveReady += (s, e) =>
                        {
                            // just swallow message -> wrong service name
                            e.Socket.ReceiveMultipartMessage();
                        };

                        poller.Add(broker);
                        poller.RunAsync();

                        // set the event handler to receive the logging messages
                        session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info);
                        // well formed message
                        var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });
                        // wrong service name
                        session.Send("xyz", requestMessage);

                        poller.Stop();

                        Assert.That(loggingMessages.Count, Is.EqualTo(7));
                        Assert.That(loggingMessages[6], Is.EqualTo("[CLIENT ERROR] permanent error, abandoning!"));
                    }
        }
예제 #3
0
        public async void Run_ReceiveREPLYMessageFromThreeDifferentWorker_ShouldLogAndReturnCorrectReplies()
        {
            const string _END_POINT = "tcp://localhost:5555";
            var          log        = new List <string> ();

            var idW01 = new[] { (byte)'W', (byte)'1' };
            var idW02 = new[] { (byte)'W', (byte)'2' };
            var idW03 = new[] { (byte)'W', (byte)'3' };
            var idC01 = new[] { (byte)'C', (byte)'1' };
            var idC02 = new[] { (byte)'C', (byte)'2' };
            var idC03 = new[] { (byte)'C', (byte)'3' };

            const int _LONG_HEARTBEAT_INTERVAL = 10000;     // 10s heartbeat -> stay out of my testing for now

            using (var broker = new MDPBroker(_END_POINT, _LONG_HEARTBEAT_INTERVAL))
                using (var cts = new CancellationTokenSource())
                    using (var client01 = new MDPClient(_END_POINT, idC01))
                        using (var client02 = new MDPClient(_END_POINT, idC02))
                            using (var client03 = new MDPClient(_END_POINT, idC03))
                                using (var worker01 = new MDPWorker(_END_POINT, "echo", idW01))
                                    using (var worker02 = new MDPWorker(_END_POINT, "double echo", idW02))
                                        using (var worker03 = new MDPWorker(_END_POINT, "add hello", idW03))
                                        {
                                            broker.Bind();
                                            // collect all logging information from broker
                                            broker.LogInfoReady += (s, e) => log.Add(e.Info);
                                            // follow more details
                                            //broker.DebugInfoReady += (s, e) => debugLog.Add (e.Info);
                                            // start broker session
                                            broker.Run(cts.Token);
                                            // wait a little for broker to get started
                                            await Task.Delay(250);

                                            // get the task for simulating the worker & start it
                                            Task.Run(() => EchoWorker(worker01, _LONG_HEARTBEAT_INTERVAL), cts.Token);
                                            Task.Run(() => DoubleEchoWorker(worker02, _LONG_HEARTBEAT_INTERVAL), cts.Token);
                                            Task.Run(() => AddHelloWorker(worker03, _LONG_HEARTBEAT_INTERVAL), cts.Token);
                                            // wait a little for worker to get started & registered
                                            await Task.Delay(250);

                                            // get the task for simulating the client
                                            var client01Task = new Task(() => EchoClient(client01, "echo"));
                                            var client02Task = new Task(() => DoubleEchoClient(client02, "double echo"));
                                            var client03Task = new Task(() => AddHelloClient(client03, "add hello"));
                                            // start and wait for completion of client
                                            client01Task.Start();
                                            client02Task.Start();
                                            client03Task.Start();
                                            // the task completes when the message exchange is done
                                            Task.WaitAll(client01Task, client02Task, client03Task);
                                            // cancel the broker
                                            cts.Cancel();

                                            Assert.That(log.Count, Is.EqualTo(19));
                                            Assert.That(log.Count(s => s.Contains("READY")), Is.EqualTo(3));
                                            Assert.That(log.Count(s => s.Contains("REPLY")), Is.EqualTo(3));
                                            Assert.That(log.Count(s => s.Contains("Dispatching")), Is.EqualTo(3));
                                        }
        }
예제 #4
0
        public void Send_WrongHeaderFromBrokerNoLogging_ShouldThrowApplicationException()
        {
            const string hostAddress = "tcp://localhost:5555";

            // setup the counter socket for communication
            using (var context = NetMQContext.Create())
                using (var broker = context.CreateRouterSocket())
                    using (var poller = new Poller())
                        using (var session = new MDPClient(hostAddress))
                        {
                            broker.Bind(hostAddress);
                            // we need to pick up any message in order to avoid errors
                            broker.ReceiveReady += (s, e) =>
                            {
                                // return empty reply
                                var msg = e.Socket.ReceiveMultipartMessage();
                                // we expect to receive a 4 Frame message
                                // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"]
                                if (msg.FrameCount != 5)
                                {
                                    Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount);
                                }
                                // REQUEST socket will strip the his address + empty frame
                                // ROUTER has to add the address prelude in order to identify the correct socket(!)
                                // [REQ ADR][EMPTY]["MDPC00"]["echo"]["REQUEST"]
                                var clientAddress = msg.Pop();
                                msg.Pop(); // forget empty frame
                                var mdpVersion = msg.Pop();
                                msg.Pop(); // drop service name version
                                msg.Push("NoService");
                                msg.Push(mdpVersion);
                                msg.Push(NetMQFrame.Empty);
                                msg.Push(clientAddress); // reinsert the client's address

                                e.Socket.SendMessage(msg);
                            };

                            poller.AddSocket(broker);
                            Task.Factory.StartNew(poller.PollTillCancelled);

                            // well formed message
                            var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });

                            try
                            {
                                session.Send("echo", requestMessage);
                            }
                            catch (ApplicationException ex)
                            {
                                Assert.That(ex.Message, Is.EqualTo("[CLIENT INFO] answered by wrong service: NoService"));
                            }

                            poller.CancelAndJoin();
                            poller.RemoveSocket(broker);
                        }
        }
예제 #5
0
        public void ctor_NewUp_ShouldReturnMDPClient()
        {
            var session = new MDPClient("tcp://localhost:5555");

            Assert.That(session, Is.Not.Null);
            Assert.That(session.Retries, Is.EqualTo(3));
            Assert.That(session.Timeout, Is.EqualTo(TimeSpan.FromMilliseconds(2500)));

            session.Dispose();
        }
예제 #6
0
        public void MDPClientSendMessageTest()
        {
            var target = new MDPClient("tcp://localhost:5555");     // Create MDP Client to send messages to

            const string message = "hello world";
            const string service = "ECHO";

            var reply = target.SendMessage(message, service);

            Assert.AreEqual(message, reply);
        }
예제 #7
0
        public async void Run_ReceiveREPLYMessageFromWorker_ShouldLogCorrectReply()
        {
            const string endPoint = "tcp://localhost:5555";
            var          log      = new List <string> ();
            var          debugLog = new List <string> ();

            var idW01 = new[] { (byte)'W', (byte)'1' };
            var idC01 = new[] { (byte)'C', (byte)'1' };

            const int longHeartbeatInterval = 10000; // 10s heartbeat -> stay out of my testing for now

            using (var broker = new MDPBroker(endPoint, longHeartbeatInterval))
                using (var cts = new CancellationTokenSource())
                    using (var echoClient = new MDPClient(endPoint, idC01))
                        using (var echoWorker = new MDPWorker(endPoint, "echo", idW01))
                        {
                            broker.Bind();
                            // collect all logging information from broker
                            broker.LogInfoReady += (s, e) => log.Add(e.Info);
                            // follow more details
                            broker.DebugInfoReady += (s, e) => debugLog.Add(e.Info);
                            // start broker session
                            broker.Run(cts.Token);
                            // wait a little for broker to get started
                            await Task.Delay(250);

                            // get the task for simulating the worker & start it
                            Task.Run(() => EchoWorker.Run(echoWorker, longHeartbeatInterval), cts.Token);
                            // wait a little for worker to get started & registered
                            await Task.Delay(250);

                            // get the task for simulating the client
                            var echoClientTask = new Task(() => EchoClient(echoClient, "echo"));
                            // start and wait for completion of client
                            echoClientTask.Start();
                            // the task completes when the message exchange is done
                            await echoClientTask;
                            // cancel the broker
                            cts.Cancel();

                            Assert.That(log.Count, Is.EqualTo(2));
                            Assert.That(log.Count(s => s.Contains("Starting to listen for incoming messages")), Is.EqualTo(1));
                            Assert.That(log.Count(s => s.Contains("READY processed. Worker W1 added to service echo")), Is.EqualTo(1));

                            if (debugLog.Count > 0)
                            {
                                Assert.That(debugLog.Count, Is.EqualTo(16));
                                Assert.That(debugLog.Count(s => s.Contains("Received")), Is.EqualTo(3));
                                Assert.That(debugLog.Contains("[MDP BROKER DEBUG] Dispatching -> NetMQMessage[C1,,Helo World!] to echo"));
                                Assert.That(debugLog.Contains("[MDP BROKER DEBUG] REPLY from W1 received and send to C1 -> NetMQMessage[MDPC01,echo,Helo World!]"));
                            }
                        }
        }
예제 #8
0
        public void Send_CorrectInputWithLogging_ShouldReturnCorrectReply()
        {
            const string hostAddress     = "tcp://localhost:5555";
            var          loggingMessages = new List <string>();

            // setup the counter socket for communication
            using (var context = NetMQContext.Create())
                using (var broker = context.CreateRouterSocket())
                    using (var poller = new Poller())
                        using (var session = new MDPClient(hostAddress))
                        {
                            broker.Bind(hostAddress);
                            // we need to pick up any message in order to avoid errors
                            broker.ReceiveReady += (s, e) =>

                            {
                                var msg = e.Socket.ReceiveMultipartMessage();
                                // we expect to receive a 4 Frame message
                                // [client adrR][e][mdp header][service][request]
                                if (msg.FrameCount != 5)
                                {
                                    Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount);
                                }
                                // REQUEST socket will strip the his address + empty frame
                                // ROUTER has to add the address prelude in order to identify the correct socket(!)
                                // [client adr][e][mdp header][service][reply]
                                var request = msg.Last.ConvertToString();    // get the request string
                                msg.RemoveFrame(msg.Last);                   // remove the request frame
                                msg.Append(new NetMQFrame(request + " OK")); // append the reply frame
                                e.Socket.SendMessage(msg);
                            };

                            poller.AddSocket(broker);
                            Task.Factory.StartNew(poller.PollTillCancelled);
                            // set the event handler to receive the logging messages
                            session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info);
                            // well formed message
                            var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });
                            // correct call
                            var reply = session.Send("echo", requestMessage);

                            poller.CancelAndJoin();
                            poller.RemoveSocket(broker);

                            Assert.That(reply.FrameCount, Is.EqualTo(1));
                            Assert.That(reply.First.ConvertToString(), Is.EqualTo("REQUEST OK"));
                            Assert.That(loggingMessages.Count, Is.EqualTo(3));
                            Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555"));
                            Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True);
                            Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True);
                        }
        }
예제 #9
0
        public void Send_WrongMDPVersionFromBrokerNoLogging_ShouldThrowApplicationException()
        {
            const string hostAddress = "tcp://localhost:5555";

            // setup the counter socket for communication
            using (var broker = new RouterSocket())
                using (var poller = new NetMQPoller())
                    using (var session = new MDPClient(hostAddress))
                    {
                        broker.Bind(hostAddress);
                        // we need to pick up any message in order to avoid errors
                        broker.ReceiveReady += (s, e) =>
                        {
                            // return empty reply
                            var msg = e.Socket.ReceiveMultipartMessage();
                            // we expect to receive a 4 Frame message
                            // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"]
                            if (msg.FrameCount != 5)
                            {
                                Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount);
                            }
                            // REQUEST socket will strip the his address + empty frame
                            // ROUTER has to add the address prelude in order to identify the correct socket(!)
                            // [REQ ADR][EMPTY]["MDPC00"]["echo"]["REQUEST"]
                            var clientAddress = msg.Pop();
                            msg.Pop();               // forget empty frame
                            msg.Pop();               // drop the MDP Version Frame
                            msg.Push("MDPC00");      // insert wrong MDP version
                            msg.Push(NetMQFrame.Empty);
                            msg.Push(clientAddress); // reinsert the client's address

                            e.Socket.SendMultipartMessage(msg);
                        };

                        poller.Add(broker);
                        poller.RunAsync();

                        // well formed message
                        var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });

                        try
                        {
                            session.Send("echo", requestMessage);
                        }
                        catch (ApplicationException ex)
                        {
                            Assert.That(ex.Message, Is.StringContaining("MDP Version mismatch"));
                        }
                    }
        }
예제 #10
0
        public void Send_EmptyReplyFromBrokerWithLogging_ShouldThrowApplicationException()
        {
            const string hostAddress     = "tcp://localhost:5555";
            var          loggingMessages = new List <string>();

            // setup the counter socket for communication
            using (var context = NetMQContext.Create())
                using (var broker = context.CreateRouterSocket())
                    using (var poller = new Poller())
                        using (var session = new MDPClient(hostAddress))
                        {
                            broker.Bind(hostAddress);
                            // we need to pick up any message in order to avoid errors
                            broker.ReceiveReady += (s, e) =>
                            {
                                // return empty reply
                                var msg = e.Socket.ReceiveMultipartMessage();
                                // we expect to receive a 4 Frame message
                                // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"]
                                if (msg.FrameCount != 5)
                                {
                                    Assert.Fail("Message with wrong count of frames {0}", msg.FrameCount);
                                }
                                // REQUEST socket will strip the his address + empty frame
                                // ROUTER has to add the address prelude in order to identify the correct socket(!)
                                // [REQ ADR][EMPTY]["MDPC01"]["echo"]["REQUEST"]
                                e.Socket.SendMessage(msg);
                            };

                            poller.AddSocket(broker);
                            Task.Factory.StartNew(poller.PollTillCancelled);

                            // set the event handler to receive the logging messages
                            session.LogInfoReady += (s, e) => loggingMessages.Add(e.Info);
                            // well formed message
                            var requestMessage = new NetMQMessage(new[] { new NetMQFrame("REQUEST") });
                            // correct call
                            session.Send("echo", requestMessage);

                            poller.CancelAndJoin();
                            poller.RemoveSocket(broker);

                            Assert.That(loggingMessages.Count, Is.EqualTo(3));
                            Assert.That(loggingMessages[0], Is.EqualTo("[CLIENT] connecting to broker at tcp://localhost:5555"));
                            Assert.That(loggingMessages[1].Contains("[CLIENT INFO] sending"), Is.True);
                            Assert.That(loggingMessages[2].Contains("[CLIENT INFO] received"), Is.True);
                        }
        }
예제 #11
0
        public async void Run_ProcessMultipleRequestsWithMultipleClientsAndMultipleWorker_ShouldCorrectlyRouteReplies()
        {
            const string _END_POINT = "tcp://localhost:5555";
            var          log        = new List <string> ();

            var idW01 = new[] { (byte)'W', (byte)'1' };
            var idW02 = new[] { (byte)'W', (byte)'2' };
            var idC01 = new[] { (byte)'C', (byte)'1' };
            var idC02 = new[] { (byte)'C', (byte)'2' };

            const int _LONG_HEARTBEAT_INTERVAL = 10000;     // 10s heartbeat -> stay out of my testing for now

            using (var broker = new MDPBroker(_END_POINT, _LONG_HEARTBEAT_INTERVAL))
                using (var cts = new CancellationTokenSource())
                    using (var client1 = new MDPClient(_END_POINT, idC01))
                        using (var client2 = new MDPClient(_END_POINT, idC02))
                            using (var worker1 = new MDPWorker(_END_POINT, "echo", idW01))
                                using (var worker2 = new MDPWorker(_END_POINT, "echo", idW02))
                                {
                                    broker.Bind();
                                    // collect all logging information from broker
                                    broker.LogInfoReady += (s, e) => log.Add(e.Info);
                                    // follow more details
                                    //broker.DebugInfoReady += (s, e) => debugLog.Add (e.Info);
                                    // start broker session
                                    broker.Run(cts.Token);
                                    // wait a little for broker to get started
                                    await Task.Delay(250);

                                    // get the task for simulating the worker & start it
                                    Task.Run(() => MultipleRequestWorker(worker1, heartbeatinterval: _LONG_HEARTBEAT_INTERVAL), cts.Token);
                                    Task.Run(() => MultipleRequestWorker(worker2, heartbeatinterval: _LONG_HEARTBEAT_INTERVAL), cts.Token);
                                    // wait a little for worker to get started & registered
                                    await Task.Delay(250);

                                    // Create and run
                                    var c1 = Task.Run(() => MultipleRequestClient("echo", _END_POINT, client1));
                                    var c2 = Task.Run(() => MultipleRequestClient("echo", _END_POINT, client2));

                                    Task.WaitAll(c1, c2);
                                    // cancel the broker
                                    cts.Cancel();
                                }
        }
예제 #12
0
        /// <summary>
        ///     usage:  MDPServiceDiscoveryClientExample [-v]
        ///
        ///     implements a MDPClient API usage with Service Discovery
        /// </summary>
        static void Main(string[] args)
        {
            const string service_to_lookup = "echo";
            const string service_discovery = "mmi.service";

            var verbose = args.Length == 1 && args[0] == "-v";

            var id = Encoding.ASCII.GetBytes("SDC01");

            // give WORKER & BROKER time to settle
            Thread.Sleep(250);

            using (var session = new MDPClient("tcp://localhost:5555", id))
            {
                if (verbose)
                {
                    session.LogInfoReady += (s, e) => Console.WriteLine("{0}", e.Info);
                }

                var request = new NetMQMessage();
                // set the service name
                request.Push(service_to_lookup);
                // send the request to service discovery
                var reply = session.Send(service_discovery, request);

                if (reply != null && !reply.IsEmpty)
                {
                    var answer = reply.First.ConvertToString();

                    Console.WriteLine("Lookup {0} service returned: {1}/{2}", service_to_lookup, answer, reply);
                }
                else
                {
                    Console.WriteLine("ERROR: no response from broker, seems like broker is NOT running!");
                }
            }

            Console.Write("Exit with any key.");
            Console.ReadKey();
        }
예제 #13
0
        public async void Run_ProcessMultipleRequestsWithSingleWorker_ShouldCorrectlyRouteReplies()
        {
            const string endPoint = "tcp://localhost:5555";
            var          log      = new List <string> ();

            var idW01 = new[] { (byte)'W', (byte)'1' };
            var idC01 = new[] { (byte)'C', (byte)'1' };

            const int longHeartbeatInterval = 10000; // 10s heartbeat -> stay out of my testing for now

            using (var broker = new MDPBroker(endPoint, longHeartbeatInterval))
                using (var cts = new CancellationTokenSource())
                    using (var client = new MDPClient(endPoint, idC01))
                        using (var worker = new MDPWorker(endPoint, "echo", idW01))
                        {
                            broker.Bind();
                            // collect all logging information from broker
                            broker.LogInfoReady += (s, e) => log.Add(e.Info);
                            // follow more details
                            //broker.DebugInfoReady += (s, e) => debugLog.Add (e.Info);
                            // start broker session
                            broker.Run(cts.Token);
                            // wait a little for broker to get started
                            await Task.Delay(250);

                            // get the task for simulating the worker & start it
                            Task.Run(() => MultipleRequestWorker(worker, heartbeatinterval: longHeartbeatInterval), cts.Token);
                            // wait a little for worker to get started & registered
                            await Task.Delay(250);

                            // Create and run
                            await Task.Run(() => MultipleRequestClient ("echo", endPoint, client));

                            // cancel the broker
                            cts.Cancel();
                        }
        }
예제 #14
0
        /// <summary>
        ///     usage:  MDPClientExample [-v] [-rn] (1 ;lt n ;lt 100000 / Default == 10)
        ///
        ///     implements a MDPClient API usage
        /// </summary>
        private static void Main(string[] args)
        {
            if (args.Length == 1 || args.Length > 2)
            {
                if (!(args[0] == "-v" || args[0].Contains("-r")))
                {
                    Console.WriteLine("MDPClientExample [-v(erbose) OR -h(elp)]");
                    Console.WriteLine("\t-v => verbose");
                    Console.WriteLine("\tto stop processing use CTRL+C");

                    return;
                }
            }

            const string service_name = "echo";
            const int    max_runs     = 100000;

            bool verbose = false;
            int  runs    = 10;

            if (args.Length >= 1)
            {
                if (args.Length == 1 && args[0] == "-v")
                {
                    verbose = true;
                }
                else if (args.Length == 2)
                {
                    verbose = args[0] == "-v" || args[1] == "-v";
                }

                if (args[0].Contains("-r") || args.Length > 1)
                {
                    if (args[0].Contains("-r"))
                    {
                        runs = GetInt(args[0]);
                    }
                    else if (args[1].Contains("-r"))
                    {
                        runs = GetInt(args[1]);
                    }
                }
            }

            runs = runs == -1 ? 10 : runs > max_runs ? max_runs : runs;

            var id = new[] { (byte)'C', (byte)'1' };

            var watch = new Stopwatch();

            Console.WriteLine("Starting MDPClient and will send {0} requests to service <{1}>.", runs, service_name);
            Console.WriteLine("(writes '.' for every 100 and '|' for every 1000 requests)\n");

            try
            {
                // create MDP client and set verboseness && use automatic disposal
                using (var session = new MDPClient("tcp://localhost:5555", id))
                {
                    if (verbose)
                    {
                        session.LogInfoReady += (s, e) => Console.WriteLine("{0}", e.Info);
                    }

                    // just give everything time to settle in
                    Thread.Sleep(500);

                    watch.Start();

                    for (int count = 0; count < runs; count++)
                    {
                        var request = new NetMQMessage();
                        // set the request data
                        request.Push("Helo World!");
                        // send the request to the service
                        var reply = session.Send(service_name, request);

                        if (ReferenceEquals(reply, null))
                        {
                            break;
                        }

                        if (count % 1000 == 0)
                        {
                            Console.Write("|");
                        }
                        else
                        if (count % 100 == 0)
                        {
                            Console.Write(".");
                        }
                    }

                    watch.Stop();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR:");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);

                return;
            }

            var time = watch.Elapsed;

            Console.WriteLine("{0} request/replies in {1} ms processed! Took {2:N3} ms per REQ/REP",
                              runs,
                              time.TotalMilliseconds,
                              time.TotalMilliseconds / runs);

            Console.Write("\nExit with any key!");
            Console.ReadKey();
        }