Exemplo n.º 1
0
        public void A14_ResponseReceiverReconnects_AfterDisconnect()
        {
            // Duplex output channel without queue - it will not try to reconnect.
            IDuplexOutputChannel aDuplexOutputChannel = MessagingSystem.CreateDuplexOutputChannel(ChannelId);
            IDuplexInputChannel  aDuplexInputChannel  = MessagingSystem.CreateDuplexInputChannel(ChannelId);

            AutoResetEvent aConnectionsCompletedEvent = new AutoResetEvent(false);
            List <string>  anOpenConnections          = new List <string>();

            aDuplexInputChannel.ResponseReceiverConnected += (x, y) =>
            {
                lock (anOpenConnections)
                {
                    anOpenConnections.Add(y.ResponseReceiverId);

                    aConnectionsCompletedEvent.Set();
                }
            };

            try
            {
                aDuplexInputChannel.StartListening();
                aDuplexOutputChannel.OpenConnection();

                // Wait until the connection is open.
                aConnectionsCompletedEvent.WaitOne();

                // Disconnect the response receiver.
                aDuplexInputChannel.DisconnectResponseReceiver(aDuplexOutputChannel.ResponseReceiverId);

                // The duplex output channel will try to connect again, therefore wait until connected.
                aConnectionsCompletedEvent.WaitOne();
            }
            finally
            {
                aDuplexOutputChannel.CloseConnection();
                aDuplexInputChannel.StopListening();
            }


            Assert.AreEqual(2, anOpenConnections.Count);

            // Both connections should be same.
            Assert.AreEqual(aDuplexOutputChannel.ResponseReceiverId, anOpenConnections[0]);
            Assert.AreEqual(aDuplexOutputChannel.ResponseReceiverId, anOpenConnections[1]);
        }
        public void B02_Pinging_DisconnectResponseReceiver()
        {
            IDuplexInputChannel  aDuplexInputChannel  = MessagingSystemFactory.CreateDuplexInputChannel(ChannelId);
            IDuplexOutputChannel aDuplexOutputChannel = MessagingSystemFactory.CreateDuplexOutputChannel(ChannelId);

            AutoResetEvent aDisconnectedEvent = new AutoResetEvent(false);

            bool aDisconnectedFlag = false;

            aDuplexOutputChannel.ConnectionClosed += (x, y) =>
            {
                aDisconnectedFlag = true;
                aDisconnectedEvent.Set();
            };

            try
            {
                // Start listening.
                aDuplexInputChannel.StartListening();

                // Allow some time for pinging.
                aDuplexOutputChannel.OpenConnection();
                Thread.Sleep(2000);

                Assert.IsFalse(aDisconnectedFlag);

                // Disconnect the duplex output channel.
                aDuplexInputChannel.DisconnectResponseReceiver(aDuplexOutputChannel.ResponseReceiverId);

                aDisconnectedEvent.WaitOne();

                Assert.IsTrue(aDisconnectedFlag);
                Assert.IsFalse(aDuplexOutputChannel.IsConnected);
            }
            finally
            {
                aDuplexOutputChannel.CloseConnection();
                aDuplexInputChannel.StopListening();
            }
        }
Exemplo n.º 3
0
        // A response message is received from the request receiver.
        private void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e)
        {
            using (EneterTrace.Entering())
            {
                using (ThreadLock.Lock(myReceiverManipulatorLock))
                {
                    // Find the connection associated with the ResponseRecieverId to which this response message
                    // was delivered.
                    TConnection aConnection = myOpenConnections.FirstOrDefault(x => x.DuplexOutputChannel.ResponseReceiverId == e.ResponseReceiverId);
                    if (aConnection == null)
                    {
                        EneterTrace.Warning(TracedObject + "could not find the receiver for the incoming response message.");
                        return;
                    }

                    // Forward the response message to the client.
                    IDuplexInputChannel anInputChannel = AttachedDuplexInputChannel;
                    if (anInputChannel != null)
                    {
                        try
                        {
                            anInputChannel.SendResponseMessage(aConnection.ResponseReceiverId, e.Message);
                        }
                        catch (Exception err)
                        {
                            EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err);

                            try
                            {
                                // Forwarding the response to the client failed so disconnect the client.
                                anInputChannel.DisconnectResponseReceiver(aConnection.ResponseReceiverId);
                            }
                            catch (Exception err2)
                            {
                                EneterTrace.Warning(TracedObject + ErrorHandler.FailedToDisconnectResponseReceiver + aConnection.ResponseReceiverId, err2);
                            }

                            myOpenConnections.RemoveWhere(x =>
                            {
                                if (x.ResponseReceiverId == aConnection.ResponseReceiverId)
                                {
                                    try
                                    {
                                        x.DuplexOutputChannel.CloseConnection();
                                    }
                                    catch (Exception err2)
                                    {
                                        EneterTrace.Warning(TracedObject + ErrorHandler.FailedToCloseConnection, err2);
                                    }

                                    x.DuplexOutputChannel.ResponseMessageReceived -= OnResponseMessageReceived;
                                    x.DuplexOutputChannel.ConnectionClosed        -= OnRequestReceiverClosedConnection;

                                    return(true);
                                }

                                return(false);
                            });

                            EneterThreadPool.QueueUserWorkItem(() => Notify(ResponseReceiverDisconnected, new ResponseReceiverEventArgs(aConnection.ResponseReceiverId, aConnection.SenderAddress)));
                        }
                    }
                    else
                    {
                        EneterTrace.Error(TracedObject + "cannot send the response message when the duplex input channel is not attached.");
                    }
                }
            }
        }
Exemplo n.º 4
0
        public void A01_Reconnect_DisconnectReceiver()
        {
            IDuplexInputChannel  aDuplexInputChannel  = MessagingSystemFactory.CreateDuplexInputChannel(ChannelId);
            IDuplexOutputChannel aDuplexOutputChannel = MessagingSystemFactory.CreateDuplexOutputChannel(ChannelId);

            Reconnecter aReconnecter = new Reconnecter(aDuplexOutputChannel, TimeSpan.FromMilliseconds(300), -1);

            AutoResetEvent         aReconnectEvent     = new AutoResetEvent(false);
            DuplexChannelEventArgs aReconnectEventArgs = null;

            aReconnecter.ConnectionOpened += (x, y) =>
            {
                aReconnectEventArgs = y;
                aReconnectEvent.Set();
            };

            AutoResetEvent         aDisconnectEvent     = new AutoResetEvent(false);
            DuplexChannelEventArgs aDisconnectEventArgs = null;

            aReconnecter.ConnectionClosed += (x, y) =>
            {
                aDisconnectEventArgs = y;
                aDisconnectEvent.Set();
            };


            AutoResetEvent aConnectionOpenedEvent = new AutoResetEvent(false);

            aDuplexOutputChannel.ConnectionOpened += (x, y) =>
            {
                aConnectionOpenedEvent.Set();
            };

            AutoResetEvent aConnectionClosedEvent = new AutoResetEvent(false);

            aDuplexOutputChannel.ConnectionClosed += (x, y) =>
            {
                aConnectionClosedEvent.Set();
            };

            try
            {
                aReconnecter.EnableReconnecting();

                // Start listening.
                aDuplexInputChannel.StartListening();
                aDuplexOutputChannel.OpenConnection();
                Thread.Sleep(2000);

                Assert.IsTrue(aDuplexOutputChannel.IsConnected);
                aConnectionOpenedEvent.WaitOne();

                // Disconnect the duplexoutput channel.
                aDuplexInputChannel.DisconnectResponseReceiver(aDuplexOutputChannel.ResponseReceiverId);

                // Wait until the disconnect is notified.
                aDisconnectEvent.WaitOne();
                aConnectionClosedEvent.WaitOne();

                Assert.AreEqual(aDuplexOutputChannel.ChannelId, aDisconnectEventArgs.ChannelId);
                Assert.AreEqual(aDuplexOutputChannel.ResponseReceiverId, aDisconnectEventArgs.ResponseReceiverId);

                // Wait until the reconnecter opens connection again.
                aReconnectEvent.WaitOne();
                Assert.AreEqual(aDuplexOutputChannel.ChannelId, aReconnectEventArgs.ChannelId);
                Assert.AreEqual(aDuplexOutputChannel.ResponseReceiverId, aReconnectEventArgs.ResponseReceiverId);

                Assert.IsTrue(aDuplexOutputChannel.IsConnected);

                aConnectionOpenedEvent.WaitOne();
            }
            finally
            {
                aReconnecter.DisableReconnecting();
                aDuplexOutputChannel.CloseConnection();
                aDuplexInputChannel.StopListening();
            }
        }
Exemplo n.º 5
0
        private void UnregisterService(string serviceResponseReceiverId)
        {
            using (EneterTrace.Entering())
            {
                List <string> aClientsToDisconnect = new List <string>();

                string aServiceId = null;
                using (ThreadLock.Lock(myConnectionLock))
                {
                    // Remove the service.
                    myConnectedServices.RemoveWhere(x =>
                    {
                        if (x.ServiceResponseReceiverId == serviceResponseReceiverId)
                        {
                            aServiceId = x.ServiceId;
                            return(true);
                        }

                        return(false);
                    });

                    // Remove all clients connected to the service.
                    myConnectedClients.RemoveWhere(x =>
                    {
                        if (x.ServiceResponseReceiverId == serviceResponseReceiverId)
                        {
                            aClientsToDisconnect.Add(x.ClientResponseReceiverId);

                            // Indicate the item shall be removed.
                            return(true);
                        }

                        return(false);
                    });
                }

                // Close connections with clients.
                if (myClientConnector.IsDuplexInputChannelAttached)
                {
                    foreach (string aClientResponseReceiverId in aClientsToDisconnect)
                    {
                        IDuplexInputChannel anInputChannel = myClientConnector.AttachedDuplexInputChannel;
                        if (anInputChannel != null)
                        {
                            anInputChannel.DisconnectResponseReceiver(aClientResponseReceiverId);
                        }
                    }
                }

                IDuplexInputChannel anInputChannel2 = myServiceConnector.AttachedDuplexInputChannel;
                if (anInputChannel2 != null)
                {
                    anInputChannel2.DisconnectResponseReceiver(serviceResponseReceiverId);
                }

                if (ServiceUnregistered != null && !string.IsNullOrEmpty(aServiceId))
                {
                    EneterTrace.Debug("SERVICE '" + aServiceId + "' UNREGISTERED");

                    try
                    {
                        MessageBusServiceEventArgs anEvent = new MessageBusServiceEventArgs(aServiceId, serviceResponseReceiverId);
                        ServiceUnregistered(this, anEvent);
                    }
                    catch (Exception err)
                    {
                        EneterTrace.Error(TracedObject + ErrorHandler.DetectedException, err);
                    }
                }
            }
        }
Exemplo n.º 6
0
        private void UnregisterClient(string clientResponseReceiverId, bool sendCloseConnectionToServiceFlag, bool disconnectClientFlag)
        {
            using (EneterTrace.Entering())
            {
                // Unregistering client.
                TClientContext aClientContext = null;
                using (ThreadLock.Lock(myConnectionLock))
                {
                    myConnectedClients.RemoveWhere(x =>
                    {
                        if (x.ClientResponseReceiverId == clientResponseReceiverId)
                        {
                            aClientContext = x;
                            return(true);
                        }

                        return(false);
                    });
                }

                if (aClientContext != null)
                {
                    if (sendCloseConnectionToServiceFlag)
                    {
                        try
                        {
                            // Send close connection message to the service.
                            MessageBusMessage aMessage           = new MessageBusMessage(EMessageBusRequest.DisconnectClient, aClientContext.ClientResponseReceiverId, null);
                            object            aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(aMessage);

                            IDuplexInputChannel anInputChannel = myServiceConnector.AttachedDuplexInputChannel;
                            if (anInputChannel != null)
                            {
                                anInputChannel.SendResponseMessage(aClientContext.ServiceResponseReceiverId, aSerializedMessage);
                            }
                        }
                        catch (Exception err)
                        {
                            string anErrorMessage = TracedObject + ErrorHandler.FailedToCloseConnection;
                            EneterTrace.Warning(anErrorMessage, err);
                        }
                    }

                    // Disconnecting the client.
                    if (disconnectClientFlag)
                    {
                        IDuplexInputChannel anInputChannel1 = myClientConnector.AttachedDuplexInputChannel;
                        if (anInputChannel1 != null)
                        {
                            anInputChannel1.DisconnectResponseReceiver(aClientContext.ClientResponseReceiverId);
                        }
                    }

                    if (ClientDisconnected != null)
                    {
                        MessageBusClientEventArgs anEventArgs = new MessageBusClientEventArgs(aClientContext.ServiceId, aClientContext.ServiceResponseReceiverId, clientResponseReceiverId);
                        try
                        {
                            ClientDisconnected(this, anEventArgs);
                        }
                        catch (Exception err)
                        {
                            EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                        }
                    }
                }
            }
        }
Exemplo n.º 7
0
        public void A16_RequestResponse_100_ConstantlyInterrupted()
        {
            IDuplexOutputChannel aDuplexOutputChannel           = MessagingSystem.CreateDuplexOutputChannel(ChannelId);
            IDuplexInputChannel  aDuplexInputChannel            = MessagingSystem.CreateDuplexInputChannel(ChannelId);
            IDuplexInputChannel  anUnderlyingDuplexInputChannel = aDuplexInputChannel.GetField <IDuplexInputChannel>("myInputChannel");

            Assert.NotNull(anUnderlyingDuplexInputChannel);

            AutoResetEvent anAllMessagesProcessedEvent = new AutoResetEvent(false);

            // Received messages.
            List <int> aReceivedMessages = new List <int>();

            aDuplexInputChannel.MessageReceived += (x, y) =>
            {
                lock (aReceivedMessages)
                {
                    string aReceivedMessage = y.Message as string;

                    EneterTrace.Info("Received message: " + aReceivedMessage);

                    int k = int.Parse(aReceivedMessage);
                    aReceivedMessages.Add(k);
                    k += 1000;

                    EneterTrace.Info("Sent response message: " + k.ToString());
                    aDuplexInputChannel.SendResponseMessage(y.ResponseReceiverId, k.ToString());
                }
            };

            aDuplexOutputChannel.ConnectionClosed += (x, y) =>
            {
                EneterTrace.Info("ConnectionClosed invoked in duplex output channel");

                // The buffered duplex output channel exceeded the max offline time.
                anAllMessagesProcessedEvent.Set();
            };

            // Received response messages.
            List <int> aReceivedResponseMessages = new List <int>();

            aDuplexOutputChannel.ResponseMessageReceived += (x, y) =>
            {
                lock (aReceivedResponseMessages)
                {
                    string aReceivedMessage = y.Message as string;

                    EneterTrace.Info("Received response message: " + aReceivedMessage);

                    int k = int.Parse(aReceivedMessage);
                    aReceivedResponseMessages.Add(k);

                    if (aReceivedResponseMessages.Count == 100)
                    {
                        anAllMessagesProcessedEvent.Set();
                    }
                }
            };


            try
            {
                bool aTestFinishedFlag = false;

                aDuplexInputChannel.StartListening();
                aDuplexOutputChannel.OpenConnection();


                Thread anInteruptingThread = new Thread(() =>
                {
                    for (int i = 0; i < 100 && !aTestFinishedFlag; ++i)
                    {
                        anUnderlyingDuplexInputChannel.DisconnectResponseReceiver(aDuplexOutputChannel.ResponseReceiverId);
                        Thread.Sleep(ConnectionInterruptionFrequency);
                    }
                });

                // Start constant disconnecting.
                anInteruptingThread.Start();

                for (int i = 0; i < 100; ++i)
                {
                    aDuplexOutputChannel.SendMessage(i.ToString());
                }

                // Wait until all messages are processed.
                //anAllMessagesProcessedEvent.WaitOne();
                Assert.IsTrue(anAllMessagesProcessedEvent.WaitOne(20000), "The timeout occured.");

                aTestFinishedFlag = true;
                anInteruptingThread.Join();
            }
            finally
            {
                aDuplexOutputChannel.CloseConnection();
                aDuplexInputChannel.StopListening();
            }

            aReceivedMessages.Sort();
            Assert.AreEqual(100, aReceivedMessages.Count);
            for (int i = 0; i < 100; ++i)
            {
                Assert.AreEqual(i, aReceivedMessages[i]);
            }

            aReceivedResponseMessages.Sort();
            Assert.AreEqual(100, aReceivedResponseMessages.Count);
            for (int i = 0; i < 100; ++i)
            {
                Assert.AreEqual(i + 1000, aReceivedResponseMessages[i]);
            }
        }