예제 #1
0
        protected override void OnResponseMessageReceived(object sender, DuplexChannelMessageEventArgs e)
        {
            using (EneterTrace.Entering())
            {
                if (ResponseReceived == null)
                {
                    EneterTrace.Warning(TracedObject + ErrorHandler.NobodySubscribedForMessage);
                    return;
                }

                TypedResponseReceivedEventArgs <_ResponseType> aResponseReceivedEventArgs = null;

                try
                {
                    _ResponseType aResponseMessage = mySerializer.ForResponseReceiver(AttachedDuplexOutputChannel.ResponseReceiverId).Deserialize <_ResponseType>(e.Message);
                    aResponseReceivedEventArgs = new TypedResponseReceivedEventArgs <_ResponseType>(aResponseMessage);
                }
                catch (Exception err)
                {
                    EneterTrace.Warning(TracedObject + "failed to deserialize the response message.", err);
                    aResponseReceivedEventArgs = new TypedResponseReceivedEventArgs <_ResponseType>(err);
                }

                try
                {
                    ResponseReceived(this, aResponseReceivedEventArgs);
                }
                catch (Exception err)
                {
                    EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                }
            }
        }
예제 #2
0
        private void OnResponseReceived(object sender, TypedResponseReceivedEventArgs <MultiTypedMessage> e)
        {
            using (EneterTrace.Entering())
            {
                if (e.ReceivingError == null)
                {
                    TMessageHandler aMessageHandler;

                    using (ThreadLock.Lock(myMessageHandlers))
                    {
                        myMessageHandlers.TryGetValue(e.ResponseMessage.TypeName, out aMessageHandler);
                    }

                    if (aMessageHandler != null)
                    {
                        object aMessageData;
                        try
                        {
                            aMessageData = mySerializer.ForResponseReceiver(AttachedDuplexOutputChannel.ResponseReceiverId).Deserialize(aMessageHandler.Type, e.ResponseMessage.MessageData);

                            try
                            {
                                aMessageHandler.Invoke(aMessageData, null);
                            }
                            catch (Exception err)
                            {
                                EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err);
                            }
                        }
                        catch (Exception err)
                        {
                            try
                            {
                                aMessageHandler.Invoke(null, err);
                            }
                            catch (Exception err2)
                            {
                                EneterTrace.Warning(TracedObject + ErrorHandler.DetectedException, err2);
                            }
                        }
                    }
                    else
                    {
                        EneterTrace.Warning(TracedObject + ErrorHandler.NobodySubscribedForMessage + " Message type = " + e.ResponseMessage.TypeName);
                    }
                }
                else
                {
                    EneterTrace.Warning(TracedObject + ErrorHandler.FailedToReceiveMessage, e.ReceivingError);
                }
            }
        }
예제 #3
0
        public void RegisterResponseMessageReceiver <T>(EventHandler <TypedResponseReceivedEventArgs <T> > handler)
        {
            using (EneterTrace.Entering())
            {
                if (handler == null)
                {
                    string anError = TracedObject + "failed to register handler for response message " + typeof(T).Name + " because the input parameter handler is null.";
                    EneterTrace.Error(anError);
                    throw new ArgumentNullException(anError);
                }

                using (ThreadLock.Lock(myMessageHandlers))
                {
                    TMessageHandler aMessageHandler;
                    myMessageHandlers.TryGetValue(typeof(T).Name, out aMessageHandler);
                    if (aMessageHandler != null)
                    {
                        string anError = TracedObject + "failed to register handler for response message " + typeof(T).Name + " because the handler for such class name is already registered.";
                        EneterTrace.Error(anError);
                        throw new InvalidOperationException(anError);
                    }

                    // Note: the invoking method must be cached for particular types because
                    //       during deserialization the generic argument is not available and so it would not be possible
                    //       to instantiate TypedRequestReceivedEventArgs<T>.
                    Action <object, Exception> anEventInvoker = (message, receivingError) =>
                    {
                        TypedResponseReceivedEventArgs <T> anEvent;
                        if (receivingError == null)
                        {
                            anEvent = new TypedResponseReceivedEventArgs <T>((T)message);
                        }
                        else
                        {
                            anEvent = new TypedResponseReceivedEventArgs <T>(receivingError);
                        }
                        handler(this, anEvent);
                    };
                    myMessageHandlers[typeof(T).Name] = new TMessageHandler(typeof(T), anEventInvoker);
                }
            }
        }
예제 #4
0
        public TResponse SendRequestMessage(TRequest message)
        {
            using (EneterTrace.Entering())
            {
                // During sending and receiving only one caller is allowed.
                using (ThreadLock.Lock(myRequestResponseLock))
                {
                    TypedResponseReceivedEventArgs <TResponse> aReceivedResponse = null;
                    EventHandler <TypedResponseReceivedEventArgs <TResponse> > aResponseHandler = (x, y) =>
                    {
                        aReceivedResponse = y;
                        myResponseAvailableEvent.Set();
                    };

                    mySender.ResponseReceived += aResponseHandler;

                    try
                    {
                        myResponseAvailableEvent.Reset();

                        try
                        {
                            mySender.SendRequestMessage(message);
                        }
                        catch (Exception err)
                        {
                            string anErrorMessage = TracedObject + ErrorHandler.FailedToSendMessage;
                            EneterTrace.Error(anErrorMessage, err);
                            throw;
                        }

                        // Wait auntil the response is received or the waiting was interrupted or timeout.
                        // Note: use int instead of TimeSpan due to compatibility reasons.
                        if (!myResponseAvailableEvent.WaitOne((int)myResponseReceiveTimeout.TotalMilliseconds))
                        {
                            string anErrorMessage = TracedObject + "failed to receive the response within the timeout. " + myResponseReceiveTimeout;
                            EneterTrace.Error(anErrorMessage);
                            throw new InvalidOperationException(anErrorMessage);
                        }

                        // If response data does not exist.
                        if (aReceivedResponse == null)
                        {
                            string anErrorMessage = TracedObject + "failed to receive the response.";

                            IDuplexOutputChannel anAttachedOutputChannel = mySender.AttachedDuplexOutputChannel;
                            if (anAttachedOutputChannel == null)
                            {
                                anErrorMessage += " The duplex outputchannel was detached.";
                            }
                            else if (!anAttachedOutputChannel.IsConnected)
                            {
                                anErrorMessage += " The connection was closed.";
                            }

                            EneterTrace.Error(anErrorMessage);
                            throw new InvalidOperationException(anErrorMessage);
                        }

                        // If an error occured during receving the response then throw exception.
                        if (aReceivedResponse.ReceivingError != null)
                        {
                            string anErrorMessage = TracedObject + "failed to receive the response.";
                            EneterTrace.Error(anErrorMessage, aReceivedResponse.ReceivingError);
                            throw new InvalidOperationException(anErrorMessage, aReceivedResponse.ReceivingError);
                        }

                        return(aReceivedResponse.ResponseMessage);
                    }
                    finally
                    {
                        mySender.ResponseReceived -= aResponseHandler;
                    }
                }
            }
        }