public void Setup() { //EneterTrace.DetailLevel = EneterTrace.EDetailLevel.Debug; IMessagingSystemFactory aMessaging = new SynchronousMessagingSystemFactory(); InputChannel = aMessaging.CreateDuplexInputChannel("MyChannelId"); OutputChannel = aMessaging.CreateDuplexOutputChannel("MyChannelId"); MultiTypedMessagesFactory = new MultiTypedMessagesFactory(); }
public void Setup() { //EneterTrace.DetailLevel = EneterTrace.EDetailLevel.Debug; //EneterTrace.TraceLog = new StreamWriter("d:/tracefile.txt"); IMessagingSystemFactory anUnderlyingMessaging = new SynchronousMessagingSystemFactory(); IDuplexInputChannel aMessageBusServiceInputChannel = anUnderlyingMessaging.CreateDuplexInputChannel("MyServicesAddress"); IDuplexInputChannel aMessageBusClientInputChannel = anUnderlyingMessaging.CreateDuplexInputChannel("MyClientsAddress"); myMessageBus = new MessageBusFactory().CreateMessageBus(); myMessageBus.AttachDuplexInputChannels(aMessageBusServiceInputChannel, aMessageBusClientInputChannel); MessagingSystemFactory = new MessageBusMessagingFactory("MyServicesAddress", "MyClientsAddress", anUnderlyingMessaging) { ConnectTimeout = TimeSpan.FromMilliseconds(3000) }; // Address of the service in the message bus. ChannelId = "Service1_Address"; }
public void DoNotNotifyPublisher() { // Create channels IMessagingSystemFactory aMessagingSystem = new SynchronousMessagingSystemFactory(); IDuplexInputChannel aBrokerInputChannel = aMessagingSystem.CreateDuplexInputChannel("BrokerChannel"); IDuplexOutputChannel aClient1OutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexOutputChannel aClient2OutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); // Specify in the factory that the publisher shall not be notified from its own published events. IDuplexBrokerFactory aBrokerFactory = new DuplexBrokerFactory() { IsPublisherNotified = false }; IDuplexBroker aBroker = aBrokerFactory.CreateBroker(); aBroker.AttachDuplexInputChannel(aBrokerInputChannel); IDuplexBrokerClient aClient1 = aBrokerFactory.CreateBrokerClient(); List <BrokerMessageReceivedEventArgs> aClient1ReceivedMessage = new List <BrokerMessageReceivedEventArgs>(); aClient1.BrokerMessageReceived += (x, y) => { aClient1ReceivedMessage.Add(y); }; aClient1.AttachDuplexOutputChannel(aClient1OutputChannel); IDuplexBrokerClient aClient2 = aBrokerFactory.CreateBrokerClient(); List <BrokerMessageReceivedEventArgs> aClient2ReceivedMessage = new List <BrokerMessageReceivedEventArgs>(); aClient2.BrokerMessageReceived += (x, y) => { aClient2ReceivedMessage.Add(y); }; aClient2.AttachDuplexOutputChannel(aClient2OutputChannel); aClient1.Subscribe("TypeA"); aClient2.Subscribe("TypeA"); // Notify the message. aClient2.SendMessage("TypeA", "Message A"); // Client 2 should not get the notification. Assert.AreEqual(1, aClient1ReceivedMessage.Count); Assert.AreEqual(0, aClient2ReceivedMessage.Count); Assert.AreEqual("TypeA", aClient1ReceivedMessage[0].MessageTypeId); Assert.AreEqual("Message A", (String)aClient1ReceivedMessage[0].Message); }
public void Setup() { IMessagingSystemFactory aGlobalChannelFactory = new SynchronousMessagingSystemFactory(); myDuplexGlobalOutputChannel = aGlobalChannelFactory.CreateDuplexOutputChannel("MainChannel"); myDuplexGlobalInputChannel = aGlobalChannelFactory.CreateDuplexInputChannel("MainChannel"); myMessagingForWrapper = new SynchronousMessagingSystemFactory(); myMessagingForUnwrapper = new SynchronousMessagingSystemFactory(); IChannelWrapperFactory aFactory = new ChannelWrapperFactory(); myDuplexChannelWrapper = aFactory.CreateDuplexChannelWrapper(); myDuplexChannelUnwrapper = aFactory.CreateDuplexChannelUnwrapper(myMessagingForUnwrapper); }
public void SubscribeSameMessageTwice() { // Create channels IMessagingSystemFactory aMessagingSystem = new SynchronousMessagingSystemFactory(); IDuplexInputChannel aBrokerInputChannel = aMessagingSystem.CreateDuplexInputChannel("BrokerChannel"); IDuplexOutputChannel aSubscriberClientOutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexOutputChannel aPublisherClientOutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexBrokerFactory aBrokerFactory = new DuplexBrokerFactory(); IDuplexBroker aBroker = aBrokerFactory.CreateBroker(); aBroker.AttachDuplexInputChannel(aBrokerInputChannel); IDuplexBrokerClient aSubscriber = aBrokerFactory.CreateBrokerClient(); List <BrokerMessageReceivedEventArgs> aClient1ReceivedMessage = new List <BrokerMessageReceivedEventArgs>(); aSubscriber.BrokerMessageReceived += (x, y) => { aClient1ReceivedMessage.Add(y); }; aSubscriber.AttachDuplexOutputChannel(aSubscriberClientOutputChannel); IDuplexBrokerClient aPublisher = aBrokerFactory.CreateBrokerClient(); aPublisher.AttachDuplexOutputChannel(aPublisherClientOutputChannel); // Subscribe the 1st time. aSubscriber.Subscribe("TypeA"); // Subscribe the 2nd time. aSubscriber.Subscribe("TypeA"); // Notify the message. aPublisher.SendMessage("TypeA", "Message A"); // Although the client is subscribed twice, the message shall be notified once. Assert.AreEqual(1, aClient1ReceivedMessage.Count); Assert.AreEqual("TypeA", aClient1ReceivedMessage[0].MessageTypeId); Assert.AreEqual("Message A", (String)aClient1ReceivedMessage[0].Message); }
public void NotifySubscribers() { //EneterTrace.DetailLevel = EneterTrace.EDetailLevel.Debug; //EneterTrace.TraceLog = new StreamWriter("d:/tracefile.txt"); // Create channels IMessagingSystemFactory aMessagingSystem = new SynchronousMessagingSystemFactory(); IDuplexInputChannel aBrokerInputChannel = aMessagingSystem.CreateDuplexInputChannel("BrokerChannel"); IDuplexOutputChannel aSubscriber1ClientOutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexOutputChannel aSubscriber2ClientOutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexOutputChannel aSubscriber3ClientOutputChannel = aMessagingSystem.CreateDuplexOutputChannel("BrokerChannel"); IDuplexBrokerFactory aBrokerFactory = new DuplexBrokerFactory(); IDuplexBroker aBroker = aBrokerFactory.CreateBroker(); BrokerMessageReceivedEventArgs aBrokerReceivedMessage = null; aBroker.BrokerMessageReceived += (x, y) => { aBrokerReceivedMessage = y; }; aBroker.AttachDuplexInputChannel(aBrokerInputChannel); IDuplexBrokerClient aBrokerClient1 = aBrokerFactory.CreateBrokerClient(); BrokerMessageReceivedEventArgs aClient1ReceivedMessage = null; aBrokerClient1.BrokerMessageReceived += (x, y) => { aClient1ReceivedMessage = y; }; aBrokerClient1.AttachDuplexOutputChannel(aSubscriber1ClientOutputChannel); IDuplexBrokerClient aBrokerClient2 = aBrokerFactory.CreateBrokerClient(); BrokerMessageReceivedEventArgs aClient2ReceivedMessage = null; aBrokerClient2.BrokerMessageReceived += (x, y) => { aClient2ReceivedMessage = y; }; aBrokerClient2.AttachDuplexOutputChannel(aSubscriber2ClientOutputChannel); IDuplexBrokerClient aBrokerClient3 = aBrokerFactory.CreateBrokerClient(); BrokerMessageReceivedEventArgs aClient3ReceivedMessage = null; aBrokerClient3.BrokerMessageReceived += (x, y) => { aClient3ReceivedMessage = y; }; aBrokerClient3.AttachDuplexOutputChannel(aSubscriber3ClientOutputChannel); string[] aSubscription1 = { "TypeA", "TypeB" }; aBrokerClient1.Subscribe(aSubscription1); string[] aSubscription2 = { "TypeA" }; aBrokerClient2.Subscribe(aSubscription2); string[] aSubscription3 = { "MTypeC" }; aBrokerClient3.Subscribe(aSubscription3); aBroker.Subscribe("TypeA"); aBrokerClient3.SendMessage("TypeA", "Message A"); Assert.AreEqual("TypeA", aClient1ReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aClient1ReceivedMessage.Message); Assert.AreEqual(null, aClient1ReceivedMessage.ReceivingError); Assert.AreEqual("TypeA", aClient2ReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aClient2ReceivedMessage.Message); Assert.AreEqual(null, aClient2ReceivedMessage.ReceivingError); Assert.AreEqual(null, aClient3ReceivedMessage); Assert.AreEqual("TypeA", aBrokerReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aBrokerReceivedMessage.Message); Assert.AreEqual(null, aBrokerReceivedMessage.ReceivingError); aClient1ReceivedMessage = null; aClient2ReceivedMessage = null; aClient3ReceivedMessage = null; aBrokerReceivedMessage = null; aBrokerClient2.Unsubscribe(); aBrokerClient3.SendMessage("MTypeC", "Message MTC"); Assert.AreEqual(null, aClient1ReceivedMessage); Assert.AreEqual(null, aClient2ReceivedMessage); Assert.AreEqual("MTypeC", aClient3ReceivedMessage.MessageTypeId); Assert.AreEqual("Message MTC", (string)aClient3ReceivedMessage.Message); Assert.AreEqual(null, aClient3ReceivedMessage.ReceivingError); Assert.AreEqual(null, aBrokerReceivedMessage); aClient1ReceivedMessage = null; aClient2ReceivedMessage = null; aClient3ReceivedMessage = null; aBrokerReceivedMessage = null; aBroker.SendMessage("TypeA", "Message A"); Assert.AreEqual("TypeA", aClient1ReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aClient1ReceivedMessage.Message); Assert.AreEqual(null, aClient1ReceivedMessage.ReceivingError); Assert.AreEqual(null, aClient2ReceivedMessage); Assert.AreEqual(null, aClient3ReceivedMessage); Assert.AreEqual("TypeA", aBrokerReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aBrokerReceivedMessage.Message); Assert.AreEqual(null, aBrokerReceivedMessage.ReceivingError); aClient1ReceivedMessage = null; aClient2ReceivedMessage = null; aClient3ReceivedMessage = null; aBrokerReceivedMessage = null; aBroker.Unsubscribe("TypeA"); string[] aNewMessageType = { "TypeA" }; aBrokerClient3.Subscribe(aNewMessageType); aBrokerClient1.DetachDuplexOutputChannel(); aBrokerClient3.SendMessage("TypeA", "Message A"); Assert.AreEqual(null, aClient1ReceivedMessage); Assert.AreEqual(null, aClient2ReceivedMessage); Assert.AreEqual("TypeA", aClient3ReceivedMessage.MessageTypeId); Assert.AreEqual("Message A", (string)aClient3ReceivedMessage.Message); Assert.AreEqual(null, aClient3ReceivedMessage.ReceivingError); Assert.AreEqual(null, aBrokerReceivedMessage); }
public void LoadBalancerConnectionLogic() { IMessagingSystemFactory aMessaging = new SynchronousMessagingSystemFactory(); string aReceiverChannelId = ""; EventHandler <DuplexChannelMessageEventArgs> aRequestReceived = (x, y) => { // Echo the message. IDuplexInputChannel anInputChannel = (IDuplexInputChannel)x; aReceiverChannelId = anInputChannel.ChannelId; anInputChannel.SendResponseMessage(y.ResponseReceiverId, y.Message); }; string aResponseReceiverId = ""; ResponseReceiverEventArgs aDisconnectedLoadBalancerConnection = null; EventHandler <ResponseReceiverEventArgs> aDisconnectedFromReceiver = (x, y) => { aResponseReceiverId = ((IDuplexInputChannel)x).ChannelId; aDisconnectedLoadBalancerConnection = y; }; // Receivers. IDuplexInputChannel[] aReceivers = new IDuplexInputChannel[3]; for (int i = 0; i < aReceivers.Length; ++i) { aReceivers[i] = aMessaging.CreateDuplexInputChannel((i + 1).ToString()); aReceivers[i].MessageReceived += aRequestReceived; aReceivers[i].ResponseReceiverDisconnected += aDisconnectedFromReceiver; } // Clients. IDuplexOutputChannel aClient1 = aMessaging.CreateDuplexOutputChannel("LB"); string aReceivedResponse1 = ""; aClient1.ResponseMessageReceived += (x, y) => { aReceivedResponse1 = (string)y.Message; }; IDuplexOutputChannel aClient2 = aMessaging.CreateDuplexOutputChannel("LB"); string aReceivedResponse2 = ""; aClient2.ResponseMessageReceived += (x, y) => { aReceivedResponse2 = (string)y.Message; }; // Load Balancer ILoadBalancerFactory aLoadBalancerFactory = new RoundRobinBalancerFactory(aMessaging); ILoadBalancer aLoadBalancer = aLoadBalancerFactory.CreateLoadBalancer(); AutoResetEvent aReceiverRemovedEvent = new AutoResetEvent(false); string aRemovedReceiverId = ""; aLoadBalancer.RequestReceiverRemoved += (x, y) => { aRemovedReceiverId = y.ChannelId; aReceiverRemovedEvent.Set(); }; try { // Receivers start listening. foreach (IDuplexInputChannel aReceiver in aReceivers) { aReceiver.StartListening(); } // Load Balancer starts listening. for (int i = 0; i < aReceivers.Length; ++i) { aLoadBalancer.AddDuplexOutputChannel((i + 1).ToString()); } aLoadBalancer.AttachDuplexInputChannel(aMessaging.CreateDuplexInputChannel("LB")); // Clients connect the load balancer. aClient1.OpenConnection(); aClient2.OpenConnection(); // It shall use the next (second) receiver. aClient1.SendMessage("Hello."); Assert.AreEqual("Hello.", aReceivedResponse1); Assert.AreEqual("", aReceivedResponse2); Assert.AreEqual("2", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; // It shall use the next (third) receiver. aClient2.SendMessage("Hello."); Assert.AreEqual("", aReceivedResponse1); Assert.AreEqual("Hello.", aReceivedResponse2); Assert.AreEqual("3", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; // It is at the end of the pool so it shall starts from the beginning. aClient2.SendMessage("Hello."); Assert.AreEqual("", aReceivedResponse1); Assert.AreEqual("Hello.", aReceivedResponse2); Assert.AreEqual("1", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; // Let's remove the second receiver. aLoadBalancer.RemoveDuplexOutputChannel("2"); Assert.IsNotNull(aDisconnectedLoadBalancerConnection); Assert.AreEqual("2", aResponseReceiverId); // The 2nd is removed so it shall use the 3rd one. aClient2.SendMessage("Hello."); Assert.AreEqual("", aReceivedResponse1); Assert.AreEqual("Hello.", aReceivedResponse2); Assert.AreEqual("3", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; // 1st receiver stops to listen. aReceivers[0].StopListening(); // It should start from the beginnng but 1st is not listening and 2nd was removed. // So it shall use the 3rd one. aClient1.SendMessage("Hello."); Assert.AreEqual("Hello.", aReceivedResponse1); Assert.AreEqual("", aReceivedResponse2); Assert.AreEqual("3", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; aReceiverRemovedEvent.WaitOne(); Assert.AreEqual("1", aRemovedReceiverId); aReceivers[2].StopListening(); aClient2.SendMessage("Hello."); Assert.AreEqual("", aReceivedResponse1); Assert.AreEqual("", aReceivedResponse2); aReceivedResponse1 = ""; aReceivedResponse2 = ""; aReceiverRemovedEvent.WaitOne(); Assert.AreEqual("3", aRemovedReceiverId); aReceivers[0].StartListening(); aReceivers[2].StartListening(); for (int i = 0; i < aReceivers.Length; ++i) { aLoadBalancer.AddDuplexOutputChannel((i + 1).ToString()); } aClient2.SendMessage("Hello."); Assert.AreEqual("", aReceivedResponse1); Assert.AreEqual("Hello.", aReceivedResponse2); Assert.AreEqual("2", aReceiverChannelId); aReceivedResponse1 = ""; aReceivedResponse2 = ""; } finally { aClient1.CloseConnection(); aClient2.CloseConnection(); aLoadBalancer.DetachDuplexInputChannel(); foreach (IDuplexInputChannel aReceiver in aReceivers) { aReceiver.StopListening(); } } }
public void RemoveConnectedService() { IMessagingSystemFactory aServiceMessaging = new TcpMessagingSystemFactory(); IMessagingSystemFactory aLocalMessaging = new SynchronousMessagingSystemFactory(); // Create services. TService aService1 = new TService(aServiceMessaging, "tcp://127.0.0.1:8097/"); TService aService2 = new TService(aServiceMessaging, "tcp://127.0.0.1:8098/"); // Create the backup router. IBackupConnectionRouterFactory aBackupRouterFactory = new BackupConnectionRouterFactory(aServiceMessaging); IBackupConnectionRouter aBackupRouter = aBackupRouterFactory.CreateBackupConnectionRouter(); List <RedirectEventArgs> aRedirections = new List <RedirectEventArgs>(); AutoResetEvent aFailedRedirectionsCompleted = new AutoResetEvent(false); int aFailedRedirections = 0; aBackupRouter.AllRedirectionsFailed += (x, y) => { ++aFailedRedirections; if (aFailedRedirections == 2) { aFailedRedirectionsCompleted.Set(); } }; aBackupRouter.AddReceivers(new string[] { "tcp://127.0.0.1:8097/", "tcp://127.0.0.1:8098/" }); IDuplexInputChannel aBackupRouterInputChannel = aLocalMessaging.CreateDuplexInputChannel("BackupRouter"); aBackupRouter.AttachDuplexInputChannel(aBackupRouterInputChannel); // Create clients connected to the backup router. TClient aClient1 = new TClient(aLocalMessaging, "BackupRouter"); TClient aClient2 = new TClient(aLocalMessaging, "BackupRouter"); try { // Start both services. aService1.myInputChannel.StartListening(); aService2.myInputChannel.StartListening(); // Connect client 1 and 2. aClient1.myOutputChannel.OpenConnection(); aClient2.myOutputChannel.OpenConnection(); Thread.Sleep(300); Assert.AreEqual(2, aService1.myConnectedClients.Count); // Remove service1 from available services. aBackupRouter.RemoveReceiver(aService1.myInputChannel.ChannelId); // Give some time to redirect clients to service 2. Thread.Sleep(1000); // Send the request message. - the router reopen the connection when the message is sent. aClient1.myOutputChannel.SendMessage("Hello from 1"); aClient1.myResponseMessageReceived.WaitOne(); aClient2.myOutputChannel.SendMessage("Hello from 2"); aClient2.myResponseMessageReceived.WaitOne(); Assert.AreEqual(2, aService2.myReceivedMessages.Count); Assert.AreEqual("Hello from 1", aService2.myReceivedMessages[0]); Assert.AreEqual("Hello from 2", aService2.myReceivedMessages[1]); Assert.AreEqual(1, aClient1.myReceivedResponses.Count); Assert.AreEqual(1, aClient2.myReceivedResponses.Count); Assert.AreEqual("Response for Hello from 1", aClient1.myReceivedResponses[0]); Assert.AreEqual("Response for Hello from 2", aClient2.myReceivedResponses[0]); } finally { aBackupRouter.RemoveAllReceivers(); aClient1.Dispose(); aClient2.Dispose(); aService1.Dispose(); aService2.Dispose(); } }
public void SendMessageReceiveResponse() { IMessagingSystemFactory aServiceMessaging = new TcpMessagingSystemFactory(); IMessagingSystemFactory aLocalMessaging = new SynchronousMessagingSystemFactory(); // Create services. TService aService1 = new TService(aServiceMessaging, "tcp://127.0.0.1:8097/"); TService aService2 = new TService(aServiceMessaging, "tcp://127.0.0.1:8098/"); // Create the backup router. IBackupConnectionRouterFactory aBackupRouterFactory = new BackupConnectionRouterFactory(aServiceMessaging); IBackupConnectionRouter aBackupRouter = aBackupRouterFactory.CreateBackupConnectionRouter(); List <RedirectEventArgs> aRedirections = new List <RedirectEventArgs>(); AutoResetEvent aRedirectionEvent = new AutoResetEvent(false); aBackupRouter.ConnectionRedirected += (x, y) => { lock (aRedirections) { aRedirections.Add(y); aRedirectionEvent.Set(); } }; aBackupRouter.AddReceivers(new string[] { "tcp://127.0.0.1:8097/", "tcp://127.0.0.1:8098/" }); Assert.AreEqual(2, aBackupRouter.AvailableReceivers.Count()); IDuplexInputChannel aBackupRouterInputChannel = aLocalMessaging.CreateDuplexInputChannel("BackupRouter"); aBackupRouter.AttachDuplexInputChannel(aBackupRouterInputChannel); // Create clients connected to the backup router. TClient aClient1 = new TClient(aLocalMessaging, "BackupRouter"); TClient aClient2 = new TClient(aLocalMessaging, "BackupRouter"); try { // Start both services. aService1.myInputChannel.StartListening(); aService2.myInputChannel.StartListening(); // Connect client 1. aClient1.myOutputChannel.OpenConnection(); Thread.Sleep(300); Assert.AreEqual(1, aService1.myConnectedClients.Count); // Disconnect client 1. aClient1.myOutputChannel.CloseConnection(); Thread.Sleep(300); Assert.AreEqual(0, aService1.myConnectedClients.Count); // Connect client 1 and 2. EneterTrace.Info("Client1 opens connection."); aClient1.myOutputChannel.OpenConnection(); EneterTrace.Info("Client2 opens connection."); aClient2.myOutputChannel.OpenConnection(); Thread.Sleep(300); Assert.AreEqual(2, aService1.myConnectedClients.Count); // Stop service 1. aService1.myInputChannel.StopListening(); aService1.myConnectedClients.Clear(); aRedirectionEvent.WaitOne(); aRedirectionEvent.WaitOne(); // Give some time until the service has connections. Thread.Sleep(500); Assert.AreEqual(2, aService2.myConnectedClients.Count); // Start service 1 again and stop Service 2. aService1.myInputChannel.StartListening(); aService2.myInputChannel.StopListening(); aService2.myConnectedClients.Clear(); aRedirectionEvent.WaitOne(); aRedirectionEvent.WaitOne(); // Give some time until the service has connections. Thread.Sleep(300); Assert.AreEqual(2, aService1.myConnectedClients.Count); aService2.myInputChannel.StartListening(); // Send the request message. aClient1.myOutputChannel.SendMessage("Hello from 1"); aClient1.myResponseMessageReceived.WaitOne(); aClient2.myOutputChannel.SendMessage("Hello from 2"); aClient2.myResponseMessageReceived.WaitOne(); Assert.AreEqual(2, aService1.myReceivedMessages.Count); Assert.AreEqual(0, aService2.myReceivedMessages.Count); Assert.AreEqual("Hello from 1", aService1.myReceivedMessages[0]); Assert.AreEqual("Hello from 2", aService1.myReceivedMessages[1]); Assert.AreEqual(1, aClient1.myReceivedResponses.Count); Assert.AreEqual(1, aClient2.myReceivedResponses.Count); Assert.AreEqual("Response for Hello from 1", aClient1.myReceivedResponses[0]); Assert.AreEqual("Response for Hello from 2", aClient2.myReceivedResponses[0]); } finally { aBackupRouter.RemoveAllReceivers(); aClient1.Dispose(); aClient2.Dispose(); aService1.Dispose(); aService2.Dispose(); } }