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)); } }
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!")); } }
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)); } }
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); } }
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(); }
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); }
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!]")); } } }
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); } }
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")); } } }
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); } }
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(); } }
/// <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(); }
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(); } }
/// <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(); }