public virtual void AttachDuplexInputChannel(IDuplexInputChannel duplexInputChannel)
        {
            using (EneterTrace.Entering())
            {
                using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock))
                {
                    Attach(duplexInputChannel);

                    try
                    {
                        AttachedDuplexInputChannel.StartListening();
                    }
                    catch (Exception err)
                    {
                        try
                        {
                            DetachDuplexInputChannel();
                        }
                        catch
                        {
                            // Ignore exception in exception.
                        }

                        EneterTrace.Error(TracedObject + ErrorHandler.FailedToStartListening, err);
                        throw;
                    }
                }
            }
        }
        /// <summary>
        /// Method is called when a response is received from the duplex output channel.
        /// It wrapps the response and sends the wrapped response to the correct response receiver as the response.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e)
        {
            using (EneterTrace.Entering())
            {
                try
                {
                    // try to find the response receiver id where the wrapped message should be responded.
                    TDuplexConnection aConnction = null;
                    using (ThreadLock.Lock(myConnections))
                    {
                        aConnction = myConnections.FirstOrDefault(x => x.DuplexOutputChannel == (IDuplexOutputChannel)sender);
                    }

                    if (aConnction != null)
                    {
                        ISerializer aSerializer = mySerializer.ForResponseReceiver(aConnction.ResponseReceiverId);

                        object aMessage = DataWrapper.Wrap(e.ChannelId, e.Message, aSerializer);
                        AttachedDuplexInputChannel.SendResponseMessage(aConnction.ResponseReceiverId, aMessage);
                    }
                    else
                    {
                        EneterTrace.Warning(TracedObject + "failed to send the response message because the response receiver id does not exist. It is possible the response receiver has already been disconnected.");
                    }
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err);
                }
            }
        }
Beispiel #3
0
        private IEnumerable <string> Send(string responseReceiverId, object serializedMessage)
        {
            using (EneterTrace.Entering())
            {
                if (AttachedDuplexInputChannel == null)
                {
                    string anErrorMessage = TracedObject + "failed to send the message because the it is not attached to duplex input channel.";
                    EneterTrace.Error(anErrorMessage);
                    throw new InvalidOperationException(anErrorMessage);
                }

                try
                {
                    AttachedDuplexInputChannel.SendResponseMessage(responseReceiverId, serializedMessage);
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + "failed to send the message. The client will be disconnected and unsubscribed from all messages.", err);

                    try
                    {
                        // Try to disconnect the client.
                        AttachedDuplexInputChannel.DisconnectResponseReceiver(responseReceiverId);
                    }
                    catch
                    {
                    }

                    // Unsubscribe the failed client.
                    return(Unsubscribe(responseReceiverId, null));
                }

                return(new string[0]);
            }
        }
        /// <summary>
        /// It is called when a response message from the service is received.
        /// The response message must be redirected to the associated client.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnOutputChannelResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e)
        {
            using (EneterTrace.Entering())
            {
                string aResponseReceiverId = null;
                using (ThreadLock.Lock(myConnectionsLock))
                {
                    TConnection aConnection = myOpenConnections.FirstOrDefault(x => x.DuplexOutputChannel.ResponseReceiverId == e.ResponseReceiverId);
                    if (aConnection != null)
                    {
                        aResponseReceiverId = aConnection.ResponseReceiverId;
                    }
                }

                if (aResponseReceiverId == null)
                {
                    EneterTrace.Warning(TracedObject + "could not find receiver for the incoming response message.");
                    return;
                }

                using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock))
                {
                    // Send the response message via the duplex input channel to the sender.
                    if (AttachedDuplexInputChannel != null)
                    {
                        try
                        {
                            AttachedDuplexInputChannel.SendResponseMessage(aResponseReceiverId, e.Message);
                        }
                        catch (Exception err)
                        {
                            EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err);
                        }
                    }
                    else
                    {
                        EneterTrace.Error(TracedObject + "cannot send the response message when the duplex input channel is not attached.");
                    }
                }
            }
        }
        public void SendResponseMessage(string responseReceiverId, string responseMessage)
        {
            using (EneterTrace.Entering())
            {
                if (AttachedDuplexInputChannel == null)
                {
                    string anError = TracedObject + "failed to send the response message because it is not attached to any duplex input channel.";
                    EneterTrace.Error(anError);
                    throw new InvalidOperationException(anError);
                }

                try
                {
                    AttachedDuplexInputChannel.SendResponseMessage(responseReceiverId, responseMessage);
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + ErrorHandler.FailedToSendResponseMessage, err);
                    throw;
                }
            }
        }
 public virtual void DetachDuplexInputChannel()
 {
     using (EneterTrace.Entering())
     {
         using (ThreadLock.Lock(myDuplexInputChannelManipulatorLock))
         {
             if (AttachedDuplexInputChannel != null)
             {
                 try
                 {
                     AttachedDuplexInputChannel.StopListening();
                 }
                 finally
                 {
                     AttachedDuplexInputChannel.MessageReceived              -= OnRequestMessageReceived;
                     AttachedDuplexInputChannel.ResponseReceiverConnected    -= OnResponseReceiverConnected;
                     AttachedDuplexInputChannel.ResponseReceiverDisconnected -= OnResponseReceiverDisconnected;
                     AttachedDuplexInputChannel = null;
                 }
             }
         }
     }
 }
Beispiel #7
0
        protected override void OnRequestMessageReceived(object sender, DuplexChannelMessageEventArgs e)
        {
            using (EneterTrace.Entering())
            {
                // Try to deserialize the message.
                BrokerMessage aBrokerMessage;
                try
                {
                    aBrokerMessage = mySerializer.ForResponseReceiver(e.ResponseReceiverId).Deserialize <BrokerMessage>(e.Message);
                }
                catch (Exception err)
                {
                    EneterTrace.Error(TracedObject + "failed to deserialize the message.", err);
                    return;
                }

                if (myValidateBrokerRequestCallback != null)
                {
                    bool isValidated = false;
                    try
                    {
                        isValidated = myValidateBrokerRequestCallback(e.ResponseReceiverId, aBrokerMessage);
                    }
                    catch (Exception err)
                    {
                        EneterTrace.Error(TracedObject + ErrorHandler.DetectedException, err);
                    }

                    if (!isValidated)
                    {
                        IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, null);
                        RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages);

                        try
                        {
                            AttachedDuplexInputChannel.DisconnectResponseReceiver(e.ResponseReceiverId);
                        }
                        catch (Exception err)
                        {
                            EneterTrace.Warning(TracedObject + "failed to disconnect response receiver.", err);
                        }
                        return;
                    }
                }

                if (aBrokerMessage.Request == EBrokerRequest.Publish)
                {
                    if (mySerializer.IsSameForAllResponseReceivers())
                    {
                        // If only one serializer is used for communication with all clients then
                        // increase the performance by reusing already serialized message.
                        Publish(e.ResponseReceiverId, aBrokerMessage, e.Message);
                    }
                    else
                    {
                        // If there is a serializer per client then the message must be serialized
                        // individually for each subscribed client.
                        Publish(e.ResponseReceiverId, aBrokerMessage, null);
                    }
                }
                else if (aBrokerMessage.Request == EBrokerRequest.Subscribe)
                {
                    Subscribe(e.ResponseReceiverId, aBrokerMessage.MessageTypes);
                }
                else if (aBrokerMessage.Request == EBrokerRequest.Unsubscribe)
                {
                    IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, aBrokerMessage.MessageTypes);
                    RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages);
                }
                else if (aBrokerMessage.Request == EBrokerRequest.UnsubscribeAll)
                {
                    IEnumerable <string> anUnsubscribedMessages = Unsubscribe(e.ResponseReceiverId, null);
                    RaiseClientUnsubscribed(e.ResponseReceiverId, anUnsubscribedMessages);
                }
            }
        }