void Worker4504InputChannel_MessageReceived(object sender, DuplexChannelMessageEventArgs e)
 {
     // echo back
     //Logger.Info(BitConverter.ToString(e.Message as byte[]));
     //string s = BitConverter.ToString(e.Message as byte[]);
     //Logger.Info("Received : " + s);
     Logger.Info("Received data length : " + (e.Message as byte[]).Length);
     //Logger.Info(e.Message.ToString());
     Worker4504InputChannel.SendResponseMessage(e.ResponseReceiverId, e.Message);
 }
        public void MulticastFromServiceToClients()
        {
            UdpMessagingSystemFactory aMessaging = new UdpMessagingSystemFactory(new EasyProtocolFormatter())
            {
                UnicastCommunication    = false,
                ReuseAddress            = true,
                MulticastGroupToReceive = "234.1.2.3",
                MulticastLoopback       = true
            };

            ManualResetEvent     aMessage1Received = new ManualResetEvent(false);
            string               aReceivedMessage1 = null;
            IDuplexOutputChannel anOutputChannel1  = aMessaging.CreateDuplexOutputChannel("udp://127.0.0.1:8090/", "udp://127.0.0.1:8092/");

            anOutputChannel1.ResponseMessageReceived += (x, y) =>
            {
                aReceivedMessage1 = (string)y.Message;
                aMessage1Received.Set();
            };

            ManualResetEvent     aMessage2Received = new ManualResetEvent(false);
            string               aReceivedMessage2 = null;
            IDuplexOutputChannel anOutputChannel2  = aMessaging.CreateDuplexOutputChannel("udp://127.0.0.1:8090/", "udp://127.0.0.1:8092/");

            anOutputChannel2.ResponseMessageReceived += (x, y) =>
            {
                aReceivedMessage2 = (string)y.Message;
                aMessage2Received.Set();
            };

            IDuplexInputChannel anInputChannel = aMessaging.CreateDuplexInputChannel("udp://127.0.0.1:8090/");

            try
            {
                anInputChannel.StartListening();

                anOutputChannel1.OpenConnection();
                anOutputChannel2.OpenConnection();

                anInputChannel.SendResponseMessage("udp://234.1.2.3:8092/", "Hello");

                aMessage1Received.WaitIfNotDebugging(1000);
                aMessage2Received.WaitIfNotDebugging(1000);
            }
            finally
            {
                anInputChannel.StopListening();

                anOutputChannel1.CloseConnection();
                anOutputChannel2.CloseConnection();
            }

            Assert.AreEqual("Hello", aReceivedMessage1);
            Assert.AreEqual("Hello", aReceivedMessage2);
        }
Exemple #3
0
        // Associate the service stub with the input channel which will be then used to send
        // messages to the client(s).
        public void AttachInputChannel(IDuplexInputChannel inputChannel)
        {
            using (EneterTrace.Entering())
            {
                myInputChannel = inputChannel;

                // Find events in the service interface and subscribe to them.
                EventInfo[] anEvents = typeof(TServiceInterface).GetEvents();
                foreach (EventInfo anEventInfo in anEvents)
                {
                    Type anEventArgsType = anEventInfo.EventHandlerType.IsGenericType ?
                                           anEventInfo.EventHandlerType.GetGenericArguments()[0] :
                                           typeof(EventArgs);

                    // This handler will be subscribed to events from the service.
                    // Note: for each loop create a new local variable so that the context is preserved for the Action<,> event handler.
                    //       if anEventInfo is used then the reference would be changed.
                    EventInfo aTmpEventInfo = anEventInfo;
                    Action <object, EventArgs> anEventHandler = (sender, e) =>
                    {
                        using (EneterTrace.Entering())
                        {
                            string[] aSubscribedClients = null;
                            using (ThreadLock.Lock(myServiceEvents))
                            {
                                EventContext anEventContextTmp = myServiceEvents.FirstOrDefault(x => x.EventInfo.Name == aTmpEventInfo.Name);
                                if (anEventContextTmp != null)
                                {
                                    aSubscribedClients = anEventContextTmp.SubscribedClients.ToArray();
                                }
                            }

                            // If some client is subscribed.
                            if (aSubscribedClients != null && aSubscribedClients.Length > 0)
                            {
                                object aSerializedEvent = null;

                                // If there is one serializer for all clients then pre-serialize the message to increase the performance.
                                if (mySerializer.IsSameForAllResponseReceivers())
                                {
                                    try
                                    {
                                        // Serialize the event and send it to subscribed clients.
                                        RpcMessage anEventMessage = new RpcMessage()
                                        {
                                            Id               = 0, // dummy - because we do not need to track it.
                                            Request          = ERpcRequest.RaiseEvent,
                                            OperationName    = aTmpEventInfo.Name,
                                            SerializedParams = (anEventArgsType == typeof(EventArgs)) ?
                                                               null : // EventArgs is a known type without parameters - we do not need to serialize it.
                                                               new object[] { mySerializer.Serialize(anEventArgsType, e) }
                                        };
                                        aSerializedEvent = mySerializer.Serialize <RpcMessage>(anEventMessage);
                                    }
                                    catch (Exception err)
                                    {
                                        EneterTrace.Error(TracedObject + "failed to serialize the event '" + aTmpEventInfo.Name + "'.", err);

                                        // Note: this exception will be thrown to the delegate that raised the event.
                                        throw;
                                    }
                                }

                                // Iterate via subscribed clients and send them the event.
                                foreach (string aClient in aSubscribedClients)
                                {
                                    try
                                    {
                                        // If there is serializer per client then serialize the message for each client.
                                        if (!mySerializer.IsSameForAllResponseReceivers())
                                        {
                                            ISerializer aSerializer = mySerializer.ForResponseReceiver(aClient);

                                            RpcMessage anEventMessage = new RpcMessage()
                                            {
                                                Id               = 0, // dummy - because we do not need to track it.
                                                Request          = ERpcRequest.RaiseEvent,
                                                OperationName    = aTmpEventInfo.Name,
                                                SerializedParams = (anEventArgsType == typeof(EventArgs)) ?
                                                                   null : // EventArgs is a known type without parameters - we do not need to serialize it.
                                                                   new object[] { aSerializer.Serialize(anEventArgsType, e) }
                                            };

                                            // Note: do not store serialized data to aSerializedEvent because
                                            //       if SendResponseMessage works asynchronously then the reference to serialized
                                            //       data could be overridden.
                                            object aSerializedEventForClient = aSerializer.Serialize <RpcMessage>(anEventMessage);

                                            myInputChannel.SendResponseMessage(aClient, aSerializedEventForClient);
                                        }
                                        else
                                        {
                                            myInputChannel.SendResponseMessage(aClient, aSerializedEvent);
                                        }
                                    }
                                    catch (Exception err)
                                    {
                                        EneterTrace.Error(TracedObject + "failed to send event '" + aTmpEventInfo.Name + "' to the client.", err);

                                        // Suppose the client is disconnected so unsubscribe it from all events.
                                        UnsubscribeClientFromEvents(aClient);

                                        // Note: do not retrow the exception because other subscribed clients would not be notified.
                                        //       E.g. if the exception occured because the client disconnected other clients should
                                        //       not be affected.
                                    }
                                }
                            }
                        }
                    };

                    EventContext anEventContext = null;
                    try
                    {
                        anEventContext = new EventContext(myService, anEventInfo, Delegate.CreateDelegate(anEventInfo.EventHandlerType, anEventHandler.Target, anEventHandler.Method));
                        anEventContext.Subscribe();
                    }
                    catch (Exception err)
                    {
                        string anErrorMessage = TracedObject + "failed to attach the output channel because it failed to create EventContext.";
                        EneterTrace.Error(anErrorMessage, err);
                        throw;
                    }

                    using (ThreadLock.Lock(myServiceEvents))
                    {
                        if (!myServiceEvents.Add(anEventContext))
                        {
                            string anErrorMessage = TracedObject + "failed to attach the output channel because it failed to create the event '" + anEventInfo.Name + "' because the event already exists.";
                            EneterTrace.Error(anErrorMessage);
                            throw new InvalidOperationException(anErrorMessage);
                        }
                    }
                }
            }
        }
        // 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.");
                    }
                }
            }
        }
Exemple #5
0
        public void A01_SimpleRequestResponse()
        {
            IDuplexOutputChannel aDuplexOutputChannel = MessagingSystem.CreateDuplexOutputChannel(ChannelId);
            IDuplexInputChannel  aDuplexInputChannel  = MessagingSystem.CreateDuplexInputChannel(ChannelId);


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

            aDuplexInputChannel.MessageReceived += (x, y) =>
            {
                //EneterTrace.Info("Message Received");
                lock (aReceivedMessages)
                {
                    string aReceivedMessage = y.Message as string;

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

                    aDuplexInputChannel.SendResponseMessage(y.ResponseReceiverId, k.ToString());
                }
            };

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

            aDuplexOutputChannel.ResponseMessageReceived += (x, y) =>
            {
                //EneterTrace.Info("Response Received");
                lock (aReceivedResponseMessages)
                {
                    string aReceivedMessage = y.Message as string;

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

                    if (k == 1019)
                    {
                        anAllMessagesProcessedEvent.Set();
                    }
                }
            };


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

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

                // Wait untill all messages are processed.
                anAllMessagesProcessedEvent.WaitOne();
            }
            finally
            {
                aDuplexOutputChannel.CloseConnection();
                aDuplexInputChannel.StopListening();
            }

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

            aReceivedResponseMessages.Sort();
            Assert.AreEqual(20, aReceivedResponseMessages.Count);
            for (int i = 0; i < 20; ++i)
            {
                Assert.AreEqual(i + 1000, aReceivedResponseMessages[i]);
            }
        }
Exemple #6
0
        private void ForwardMessageToClient(string clientResponseReceiverId, string serviceResponseReceiverId, object serializedMessage, object originalMessage)
        {
            using (EneterTrace.Entering())
            {
                // Check if the requested client id has a connection with the service session which forwards the message.
                // Note: this is to prevent that a sevice sends a message to a client which is not connected to it.
                TClientContext aClientContext;
                using (ThreadLock.Lock(myConnectionLock))
                {
                    aClientContext = myConnectedClients.FirstOrDefault(x => x.ClientResponseReceiverId == clientResponseReceiverId && x.ServiceResponseReceiverId == serviceResponseReceiverId);
                }

                if (aClientContext == null)
                {
                    // The associated client does not exist and the message canno be sent.
                    EneterTrace.Warning(TracedObject + "failed to forward the message to client because the client was not found.");
                    return;
                }

                IDuplexInputChannel anInputChannel = myClientConnector.AttachedDuplexInputChannel;
                if (anInputChannel != null)
                {
                    // Invoke sending of the message in the client particular thread.
                    // So that e.g. if there are communication problems sending to other clients
                    // is not affected.
                    aClientContext.ForwardToClientThreadDispatcher.Invoke(
                        () =>
                    {
                        using (EneterTrace.Entering())
                        {
                            try
                            {
                                anInputChannel.SendResponseMessage(clientResponseReceiverId, serializedMessage);

                                // If originalMessage is null then service forwards just confirmation the connection was open.
                                if (originalMessage == null && ClientConnected != null)
                                {
                                    MessageBusClientEventArgs anEvent = new MessageBusClientEventArgs(aClientContext.ServiceId, aClientContext.ServiceResponseReceiverId, clientResponseReceiverId);

                                    try
                                    {
                                        ClientConnected(this, anEvent);
                                    }
                                    catch (Exception err)
                                    {
                                        EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                                    }
                                }
                                // If original message is not null then the service sends a response message to the client.
                                else if (originalMessage != null && MessageToClientSent != null)
                                {
                                    MessageBusMessageEventArgs anEventArgs = new MessageBusMessageEventArgs(aClientContext.ServiceId, serviceResponseReceiverId, clientResponseReceiverId, originalMessage);
                                    try
                                    {
                                        MessageToClientSent(this, anEventArgs);
                                    }
                                    catch (Exception err)
                                    {
                                        EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                                    }
                                }
                            }
                            catch (Exception err)
                            {
                                string anErrorMessage = TracedObject + "failed to send message to the client.";
                                EneterTrace.Error(anErrorMessage, err);

                                UnregisterClient(aClientContext.ClientResponseReceiverId, true, true);
                            }
                        }
                    });
                }
            }
        }
Exemple #7
0
        private void ForwardMessageToService(string clientResponseReceiverId, MessageBusMessage messageFromClient)
        {
            using (EneterTrace.Entering())
            {
                TClientContext aClientContext = null;
                using (ThreadLock.Lock(myConnectionLock))
                {
                    aClientContext = myConnectedClients.FirstOrDefault(x => x.ClientResponseReceiverId == clientResponseReceiverId);
                }

                if (aClientContext != null)
                {
                    // Forward the incoming message to the service.
                    IDuplexInputChannel anInputChannel = myServiceConnector.AttachedDuplexInputChannel;
                    if (anInputChannel != null)
                    {
                        aClientContext.ForwardToServiceThreadDispatcher.Invoke(
                            () =>
                        {
                            using (EneterTrace.Entering())
                            {
                                try
                                {
                                    // Add the client id into the message.
                                    // Note: Because of security reasons we do not expect Ids from the client but using Ids associated with the connection session.
                                    //       Otherwise it would be possible that some client could use id of another client to pretend a different client.
                                    messageFromClient.Id      = clientResponseReceiverId;
                                    object aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(messageFromClient);

                                    anInputChannel.SendResponseMessage(aClientContext.ServiceResponseReceiverId, aSerializedMessage);

                                    if (MessageToServiceSent != null)
                                    {
                                        MessageBusMessageEventArgs anEventArgs = new MessageBusMessageEventArgs(aClientContext.ServiceId, aClientContext.ServiceResponseReceiverId, clientResponseReceiverId, messageFromClient.MessageData);
                                        try
                                        {
                                            MessageToServiceSent(this, anEventArgs);
                                        }
                                        catch (Exception err)
                                        {
                                            EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                                        }
                                    }
                                }
                                catch (Exception err)
                                {
                                    string anErrorMessage = TracedObject + "failed to send message to the service '" + aClientContext.ServiceId + "'.";
                                    EneterTrace.Error(anErrorMessage, err);

                                    UnregisterService(aClientContext.ServiceResponseReceiverId);
                                }
                            }
                        });
                    }
                }
                else
                {
                    string anErrorMessage = TracedObject + "failed to send message to the service because the client was not found.";
                    EneterTrace.Warning(anErrorMessage);
                }
            }
        }
Exemple #8
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);
                        }
                    }
                }
            }
        }
Exemple #9
0
        private void RegisterClient(string clientResponseReceiverId, string serviceId)
        {
            using (EneterTrace.Entering())
            {
                bool           anIsNewClientConnected = false;
                TClientContext aClientContext         = null;
                using (ThreadLock.Lock(myConnectionLock))
                {
                    aClientContext = myConnectedClients.FirstOrDefault(x => x.ClientResponseReceiverId == clientResponseReceiverId);

                    // If such client does not exist yet then create it.
                    if (aClientContext == null)
                    {
                        TServiceContext aServiceContext = myConnectedServices.FirstOrDefault(x => x.ServiceId == serviceId);

                        // If requested service exists.
                        if (aServiceContext != null)
                        {
                            aClientContext = new TClientContext(clientResponseReceiverId, serviceId, aServiceContext.ServiceResponseReceiverId);
                            myConnectedClients.Add(aClientContext);
                            anIsNewClientConnected = true;
                        }
                    }
                }

                if (anIsNewClientConnected)
                {
                    // Send open connection message to the service.
                    try
                    {
                        MessageBusMessage aMessage           = new MessageBusMessage(EMessageBusRequest.ConnectClient, clientResponseReceiverId, null);
                        object            aSerializedMessage = mySerializer.Serialize <MessageBusMessage>(aMessage);

                        IDuplexInputChannel anInputChannel = myServiceConnector.AttachedDuplexInputChannel;
                        if (anInputChannel != null)
                        {
                            anInputChannel.SendResponseMessage(aClientContext.ServiceResponseReceiverId, aSerializedMessage);
                        }
                    }
                    catch (Exception err)
                    {
                        EneterTrace.Warning(TracedObject + "failed to send open connection message to the service '" + aClientContext.ServiceId + "'.", err);

                        // Note: The service should not be disconnected from the message bus when not available.
                        //       Because it can be "just" overloaded. So only this new client will be disconnected from the message bus.
                        UnregisterClient(clientResponseReceiverId, false, true);
                    }
                }
                else
                {
                    if (aClientContext != null)
                    {
                        EneterTrace.Warning(TracedObject + "failed to connect the client already exists. The connection will be closed.");
                        UnregisterClient(clientResponseReceiverId, false, true);
                    }
                    else
                    {
                        EneterTrace.Warning(TracedObject + "failed to connec the client because the service '" + serviceId + "' does not exist. The connection will be closed.");
                        UnregisterClient(clientResponseReceiverId, false, true);
                    }
                }
            }
        }
        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();
                }
            }
        }
Exemple #11
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]);
            }
        }
Exemple #12
0
        private void Command_Received(object sender, StringRequestReceivedEventArgs e)
        {
            Logger.Info("Received : " + e.RequestMessage + " from " + e.ResponseReceiverId);
            try
            {
                Command_MessageReceiver.SendResponseMessage(e.ResponseReceiverId, e.RequestMessage);
            }
            catch (Exception)
            {
            }

            // Analyze message
            // split strings
            string[] received = e.RequestMessage.Split('|');
            //Logger.Info("Split");
            foreach (string s in received)
            {
                //Logger.Info(s);
            }
            // version|command|target    |param1|param2
            // 1      |send   |responseid|123456|10
            // 1      |receive|responseid|123456|10
            // 1      |notify |responseid|open  |0
            // 1      |notify |responseid|close |0

            // receiving responsereceiverid from client
            // identify command
            // TODO:Try catch
            double version = double.Parse(received[0]);
            string command = received[1];
            string target  = received[2];
            string param1  = received[3];
            string param2  = received[4];

            Logger.Info("Split " + version + " " + command + " " + target + " " + param1 + " " + param2);
            //Logger.Info("Version : " + version);
            //Logger.Info("Command : " + command);
            //Logger.Info("Target : " + target);
            //Logger.Info("Param1 : " + param1);
            //Logger.Info("Param2 : " + param2);

            if (version == 1.0)
            {
                if (command.Equals("send"))
                {
                    // convert param to appropriate type
                    // TODO:tryparse
                    int length = int.Parse(param1);
                    int repeat = int.Parse(param2);

                    // Send a message.
                    byte[] data = new byte[length];                     // initialize 1MB data
                    //byte[] data = new byte[10]; // initialize 1MB data
                    Random random = new Random();
                    random.NextBytes(data);

                    int    i = 0;
                    string s = "a";
                    Logger.Info("Start sending " + length + " bytes of data " + repeat + " times to " + target);
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    Command_MessageReceiver.SendResponseMessage(e.ResponseReceiverId, s);
                    do
                    {
                        Worker4504_InputChannel.SendResponseMessage(target, data);

                        i++;
                    } while (i < repeat);
                    s = "z";
                    Command_MessageReceiver.SendResponseMessage(e.ResponseReceiverId, s);
                    stopwatch.Stop();
                    Logger.Info("Finished sending " + length + " bytes of data " + repeat + " times to " + target + " in " + stopwatch.ElapsedMilliseconds + " milliseconds");
                }
                else if (command.Equals("receive"))
                {
                }
                else if (command.Equals("notify"))
                {
                }
                else
                {
                    Logger.Error("Unknown command : " + command);
                }
            }
            else
            {
                Logger.Error("Unknown command : " + e.RequestMessage);
            }

            // Calculate mtu
            // Warm up stopwatch
            // Send message
        }