Пример #1
0
        /// <summary>
        /// Requests processing from the current sink of the response from a method call sent asynchronously.
        /// It's a reply to a previously processed async call.
        /// Parameter state is expected to contain source message.
        /// </summary>
        /// <param name="sinkStack">A stack of sinks leading back to the server transport sink.</param>
        /// <param name="state">Information generated on the request side that is associated with this sink.</param>
        /// <param name="msg">The response message.</param>
        /// <param name="headers">The headers to add to the return message heading to the client.</param>
        /// <param name="stream">The stream heading back to the transport sink.</param>
        public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack,
                                         object state, IMessage msg, ITransportHeaders headers, Stream stream)
        {
            Message         message         = (Message)state;
            BinaryLogWriter binaryLogWriter = message.ITransportContext.BinaryLogWriter;

            Message reply = new Message(message, headers, stream);

            // LOG: put down the log record
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
            {
                string invocationTarget = msg.Properties["__Uri"] as string;
                string methodName       = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                binaryLogWriter.WriteMessageCreatedEvent("GenuineUniversalServerTransportSink.AsyncProcessResponse",
                                                         LogMessageType.MessageCreated, null, reply, false, reply.Recipient,
                                                         this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? reply.Stream : null,
                                                         invocationTarget, methodName,
                                                         GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                                                         "The response message has been created.");

                reply.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget;
                reply.ITransportHeaders[Message.TransportHeadersMethodName]       = methodName;

                binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.AsyncProcessResponse",
                                           LogMessageType.MessageRequestInvoked, null, reply, message.Sender,
                                           null,
                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                           null, null, -1, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                           "The .NET Remoting invocation has been performed.");
            }

            message.ITransportContext.ConnectionManager.Send(reply);
        }
Пример #2
0
        /// <summary>
        /// Handles incoming message (message, response or event).
        /// </summary>
        /// <param name="message">The message to handle.</param>
        public void HandleIncomingMessage(Message message)
        {
            BinaryLogWriter binaryLogWriter = message.ITransportContext.BinaryLogWriter;

            try
            {
                ServerChannelSinkStack stack = new ServerChannelSinkStack();
                stack.Push(this, message);

                ITransportHeaders responseHeaders;
                Stream            responseStream;
                IMessage          responseMsg;

                // FIX: 2.5.8 removing the application name from the object URI
                string applicationName = RemotingConfiguration.ApplicationName;
                if (applicationName != null)
                {
                    string uri = (string)message.ITransportHeaders["__RequestUri"];
                    if (uri.Length > applicationName.Length && uri.StartsWith(applicationName))
                    {
                        int sizeToBeCut = applicationName.Length + (uri[applicationName.Length] == '/' ? 1 : 0);
                        uri = uri.Substring(sizeToBeCut);
                        message.ITransportHeaders["__RequestUri"] = uri;
                    }
                }

                message.ITransportHeaders["__CustomErrorsEnabled"]       = false;
                message.ITransportHeaders[CommonTransportKeys.IPAddress] = message.Sender.PhysicalAddress is IPEndPoint ? ((IPEndPoint)message.Sender.PhysicalAddress).Address : message.Sender.PhysicalAddress;

                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                               LogMessageType.MessageRequestInvoking, null, message, message.Sender,
                                               null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, GenuineUtility.TickCount, 0, 0, null, null, null, null,
                                               "The .NET Remoting request is being invoked.");
                }

                ServerProcessing serverProcessing = this._nextChannelSink.ProcessMessage(stack, null, message.ITransportHeaders, message.Stream, out responseMsg, out responseHeaders, out responseStream);

                switch (serverProcessing)
                {
                case ServerProcessing.Complete:
                    Message reply = new Message(message, responseHeaders, responseStream);

                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                    {
                        string invocationTarget = responseMsg.Properties["__Uri"] as string;
                        string methodName       = BinaryLogWriter.ParseInvocationMethod(responseMsg.Properties["__MethodName"] as string, responseMsg.Properties["__TypeName"] as string);
                        binaryLogWriter.WriteMessageCreatedEvent("GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                                                 LogMessageType.MessageCreated, null, reply, false, reply.Recipient,
                                                                 this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? reply.Stream : null,
                                                                 invocationTarget, methodName,
                                                                 GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                                                                 "The response message has been created.");

                        reply.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget;
                        reply.ITransportHeaders[Message.TransportHeadersMethodName]       = methodName;

                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                                   LogMessageType.MessageRequestInvoked, null, reply, message.Sender,
                                                   null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                                   "The .NET Remoting invocation has been performed.");
                    }

                    message.ITransportContext.ConnectionManager.Send(reply);
                    break;

                case ServerProcessing.Async:
                    // asyncProcessResponse will be called later
                    break;

                case ServerProcessing.OneWay:
                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                                   LogMessageType.MessageRequestInvoked, null, null, message.Sender,
                                                   null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                                   "One-way .NET Remoting invocation has been performed. No response is available.");
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                try
                {
                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                                   LogMessageType.MessageRequestInvoking, ex, message, message.Sender,
                                                   null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, 0, 0, 0, null, null, null, null,
                                                   "The .NET Remoting request resulted in exception. The exception is being sent back.");
                    }

                    // return this exception as a result
                    BinaryFormatter      binaryFormatter     = new BinaryFormatter();
                    GenuineChunkedStream serializedException = new GenuineChunkedStream(false);
                    binaryFormatter.Serialize(serializedException, ex);

                    Message reply = new Message(message, new TransportHeaders(), serializedException);
                    reply.ContainsSerializedException = true;
                    this.ITransportContext.ConnectionManager.Send(reply);
                }
                catch (Exception internalEx)
                {
                    // It's a destiny not to deliver an exception back to the caller

                    // LOG: put down the log record
                    if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                    {
                        binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineUniversalServerTransportSink.HandleIncomingMessage",
                                                   LogMessageType.MessageRequestInvoking, internalEx, message, message.Sender,
                                                   null,
                                                   GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                   null, null, -1, 0, 0, 0, null, null, null, null,
                                                   "The source exception cannot be sent over the network. Both exceptions are ignored.");
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Looks for a failed broadcast receivers and invoke them again.
        /// </summary>
        public void SendMessageToFailedReceiversDirectly()
        {
            if (this._secondStagePerformed)
            {
                return;
            }

            this._secondStagePerformed = true;
            BinaryLogWriter binaryLogWriter = GenuineLoggingServices.BinaryLogWriter;

            // the second stage of the broadcasting
            using (ReaderAutoLocker reader = new ReaderAutoLocker(this._dispatcher._readerWriterLock))
            {
                // to prevent firing resultCollector.AllMessagesReceived event
                this.UnrepliedReceivers[_uniqueReceiverName] = null;

                lock (this)
                {
                    foreach (DictionaryEntry entry in this.Failed)
                    {
                        OperationException operationException = entry.Value as OperationException;
                        if (operationException != null && operationException.OperationErrorMessage != null &&
                            operationException.OperationErrorMessage.ErrorIdentifier == "GenuineChannels.Exception.Broadcast.RemoteEndPointDidNotReplyForTimeOut")
                        {
                            string       uri          = (string)entry.Key;
                            ReceiverInfo receiverInfo = this._dispatcher.GetReceiverInfo(uri);

                            // whether this receiver is expected to receive message via broadcast channel
                            if (receiverInfo == null || receiverInfo.NeedsBroadcastSimulation)
                            {
                                continue;
                            }

                            // switch it back to simulation mode if the limit is exceeded
                            lock (receiverInfo)
                            {
                                receiverInfo.NumberOfMulticastFails++;
                                if (this._dispatcher.MaximumNumberOfConsecutiveFailsToEnableSimulationMode != 0 &&
                                    receiverInfo.NumberOfMulticastFails >= this._dispatcher.MaximumNumberOfConsecutiveFailsToEnableSimulationMode)
                                {
                                    // force simulation
                                    receiverInfo.NeedsBroadcastSimulation = true;
                                    receiverInfo.NumberOfMulticastFails   = 0;
                                }
                            }

                            // each time a new stream is created because sinks change stream position concurrently
                            Stream           messageToBeSent  = (Stream)this._messageStream.Clone();
                            TransportHeaders transportHeaders = new TransportHeaders();

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                            {
                                string methodName       = BinaryLogWriter.ParseInvocationMethod(this._iMessage.Properties["__MethodName"] as string, this._iMessage.Properties["__TypeName"] as string);
                                string invocationTarget = receiverInfo.MbrUri;

                                binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.SendMessageToFailedReceiversDirectly",
                                                                          LogMessageType.BroadcastRecipientInvokedAfterTimeout, null, null, receiverInfo.DbgRemoteHost, null,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                          invocationTarget, methodName,
                                                                          "The broadcast invocation is being directed to the recipient, which did not respond during the first stage.");
                            }

                            // set destination MBR
                            this._iMessage.Properties["__Uri"] = receiverInfo.MbrUri;
                            transportHeaders[Message.TransportHeadersBroadcastObjRefOrCourt] = receiverInfo.SerializedObjRef;
                            ClientChannelSinkStack clientChannelSinkStack = new ClientChannelSinkStack(this);
                            clientChannelSinkStack.Push(this, null);
                            receiverInfo.IClientChannelSink.AsyncProcessRequest(clientChannelSinkStack, this._iMessage, transportHeaders, messageToBeSent);
                        }
                    }
                }

                this.UnrepliedReceivers.Remove(_uniqueReceiverName);
                if (this.UnrepliedReceivers.Count <= 0)
                {
                    this.AllMessagesReceived.Set();
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Sends the invocation to all registered receivers.
        /// </summary>
        /// <param name="msg">The message to be sent.</param>
        public void PerformBroadcasting(IMessage msg)
        {
            BinaryLogWriter binaryLogWriter  = GenuineLoggingServices.BinaryLogWriter;
            string          methodName       = null;
            string          invocationTarget = null;

            // the first stage of the broadcasting
            try
            {
                ArrayList listOfExcludedReceivers = new ArrayList();
                this._iMessage = msg;
                methodName     = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                BinaryFormatter formatterForLocalRecipients = null;

                // serialize the message
                BinaryFormatter binaryFormatter = new BinaryFormatter(new RemotingSurrogateSelector(), new StreamingContext(StreamingContextStates.Other));
                this._messageStream = new GenuineChunkedStream(false);
                binaryFormatter.Serialize(this._messageStream, msg);

                // to trace the message if it could reach the server via several channels
                string callGuidSubstring = null;
                if (this._dispatcher.IgnoreRecurrentCalls)
                {
                    callGuidSubstring = Guid.NewGuid().ToString("N");
                }

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                {
                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                              LogMessageType.BroadcastInvocationInitiated, null, null, null,
                                                              binaryLogWriter[LogCategory.BroadcastEngine] > 1 ? (Stream)this._messageStream.Clone() : null,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                              null, null, true, this._dispatcher, this, false, null,
                                                              methodName, null,
                                                              "The broadcast invocation is initiated.");
                }

                // to prevent firing resultCollector.AllMessagesReceived event
                this.UnrepliedReceivers[_uniqueReceiverName] = null;

                object[] listOfReceiverInfo;
                this._dispatcher.GetListOfReceivers(out listOfReceiverInfo, msg, this);

                // through all recipients
                for (int i = 0; i < listOfReceiverInfo.Length; i++)
                {
                    ReceiverInfo receiverInfo = listOfReceiverInfo[i] as ReceiverInfo;
                    if (receiverInfo == null)
                    {
                        continue;
                    }

                    string mbrUri = (string)receiverInfo.MbrUri;
                    invocationTarget = mbrUri;

                    try
                    {
                        lock (receiverInfo)
                        {
                            if (this._dispatcher.MaximumNumberOfConsecutiveFailsToExcludeReceiverAutomatically != 0 &&
                                receiverInfo.NumberOfFails >= this._dispatcher.MaximumNumberOfConsecutiveFailsToExcludeReceiverAutomatically)
                            {
                                // put it to the list containing receivers being excluded
                                listOfExcludedReceivers.Add(mbrUri);
                                continue;
                            }
                        }

                        // think that it'll fail
                        if (!receiverInfo.Local && receiverInfo.GeneralBroadcastSender == null)
                        {
                            lock (this)
                            {
                                this.Failed[mbrUri] = GenuineExceptions.Get_Broadcast_RemoteEndPointDidNotReplyForTimeOut();
                            }
                        }

                        if (receiverInfo.Local)
                        {
                            // call to local appdomain
                            // ignore recurrent calls
                            if (this._dispatcher.IgnoreRecurrentCalls && UniqueCallTracer.Instance.WasGuidRegistered(mbrUri + callGuidSubstring))
                            {
                                continue;
                            }

                            // we'll wait for the answer from this receiver
                            this.UnrepliedReceivers[mbrUri] = null;

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                            {
                                binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                          LogMessageType.BroadcastRecipientInvoked, null, null, null, null,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                          null, null,
                                                                          "The local receiver is invoked via LocalPerformer.");
                            }

                            if (formatterForLocalRecipients == null)
                            {
                                formatterForLocalRecipients = new BinaryFormatter();
                            }

                            // fixed in 2.5.9.6
                            IMessage iLocalMessage = (IMessage)formatterForLocalRecipients.Deserialize((Stream)this._messageStream.Clone());

                            // queue task to run the call locally
                            //IMessage iLocalMessage = (IMessage) binaryFormatter.Deserialize( (Stream) this._messageStream.Clone() );
                            LocalPerformer localPerformer = new LocalPerformer(iLocalMessage, this, receiverInfo.MbrObject);
                            GenuineThreadPool.QueueUserWorkItem(new WaitCallback(localPerformer.Call), null, false);
                        }
                        else if (receiverInfo.GeneralBroadcastSender != null)
                        {
                            // call via true multicast channel
                            Stream messageToBeSent = (Stream)this._messageStream.Clone();

                            // send via real broadcast sender to the specific court
                            msg.Properties["__Uri"] = string.Empty;
                            Message message = Message.CreateOutcomingMessage(receiverInfo.GeneralBroadcastSender.ITransportContext, msg, new TransportHeaders(), messageToBeSent, false);
                            message.DestinationMarshalByRef = receiverInfo.SerializedObjRef;
                            message.GenuineMessageType      = GenuineMessageType.TrueBroadcast;

                            // to ignore recurrent calls on the remote side
                            if (this._dispatcher.IgnoreRecurrentCalls)
                            {
                                message.ITransportHeaders[Message.TransportHeadersBroadcastSendGuid] = callGuidSubstring;
                            }

                            // LOG:
                            if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                            {
                                message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = invocationTarget;
                                message.ITransportHeaders[Message.TransportHeadersMethodName]       = methodName;

                                binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                          LogMessageType.BroadcastRecipientInvoked, null, null, null, null,
                                                                          GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                          null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                          null, null,
                                                                          "Mulsticast sender is being invoked.");
                            }

                            // register to catch all the answers
                            receiverInfo.GeneralBroadcastSender.ITransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, this);
                            // and send it
                            receiverInfo.GeneralBroadcastSender.SendMessage(message, this);
                        }
                        else
                        {
                            // send the invocation through the usual channel
                            // we'll wait for the reply
                            this.UnrepliedReceivers[mbrUri] = null;

                            // send only if this receiver is not expected to receive message via broadcast channel
                            if (receiverInfo.NeedsBroadcastSimulation)
                            {
                                // each time a new stream is created because sinks change stream position concurrently
                                Stream           messageToBeSent  = (Stream)this._messageStream.Clone();
                                TransportHeaders transportHeaders = new TransportHeaders();

                                // to ignore recurrent calls on the remote side
                                if (this._dispatcher.IgnoreRecurrentCalls)
                                {
                                    transportHeaders[Message.TransportHeadersBroadcastSendGuid] = callGuidSubstring;
                                }

                                // LOG:
                                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                                {
                                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                                              LogMessageType.BroadcastRecipientInvoked, null, null, receiverInfo.DbgRemoteHost, null,
                                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                                              null, null, false, this._dispatcher, this, false, receiverInfo,
                                                                              null, null,
                                                                              "The broadcast recipient is being invoked directly.");
                                }

                                // invoke the destination MBR
                                msg.Properties["__Uri"] = receiverInfo.MbrUri;
                                transportHeaders[Message.TransportHeadersBroadcastObjRefOrCourt] = receiverInfo.SerializedObjRef;
                                transportHeaders[Message.TransportHeadersMbrUriName]             = receiverInfo.MbrUri;
                                transportHeaders[Message.TransportHeadersGenuineMessageType]     = GenuineMessageType.BroadcastEngine;
                                transportHeaders[Message.TransportHeadersInvocationTarget]       = invocationTarget;
                                transportHeaders[Message.TransportHeadersMethodName]             = methodName;
                                ClientChannelSinkStack clientChannelSinkStack = new ClientChannelSinkStack(this);
                                clientChannelSinkStack.Push(this, null);
                                receiverInfo.IClientChannelSink.AsyncProcessRequest(clientChannelSinkStack, this._iMessage, transportHeaders, messageToBeSent);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        this.ParseResult(mbrUri, null, ex);
                    }
                }

                // remove set uri from the hash to check wither the invocation finished
                this.UnrepliedReceivers.Remove(_uniqueReceiverName);
                if (this.UnrepliedReceivers.Count <= 0)
                {
                    this.AllMessagesReceived.Set();
                }

                this.StartReceiving();

                if (listOfExcludedReceivers.Count > 0)
                {
                    foreach (string uri in listOfExcludedReceivers)
                    {
                        this._dispatcher.Remove(uri);
                    }
                }
            }
            catch (Exception ex)
            {
                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.BroadcastEngine] > 0)
                {
                    binaryLogWriter.WriteBroadcastEngineEvent(LogCategory.BroadcastEngine, "ResultCollector.PerformBroadcasting",
                                                              LogMessageType.BroadcastInvocationInitiated, ex, null, null, null,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                                              null, null, false, this._dispatcher, this, false, null,
                                                              invocationTarget, methodName,
                                                              "A critical failure occurred during broadcast.");
                }

                throw;
            }
        }
        /// <summary>
        /// Requests message processing from the current sink.
        /// </summary>
        /// <param name="msg">The message to process.</param>
        /// <param name="requestHeaders">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="requestStream">The stream headed to the transport sink.</param>
        /// <param name="responseHeaders">When this method returns, contains an ITransportHeaders interface that holds the headers that the server returned. This parameter is passed uninitialized.</param>
        /// <param name="responseStream">When this method returns, contains a Stream coming back from the transport sink. This parameter is passed uninitialized.</param>
        public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream,
                                   out ITransportHeaders responseHeaders, out Stream responseStream)
        {
            BinaryLogWriter   binaryLogWriter   = this.ITransportContext.BinaryLogWriter;
            ITransportContext iTransportContext = this.ITransportContext;

            if (!GenuineUtility.CheckUrlOnConnectivity(this._recipientUri))
            {
                // get the transport context from the Uri Storage
                iTransportContext = UriStorage.GetTransportContext(this._recipientUri);
                if (iTransportContext == null)
                {
                    iTransportContext = this.ITransportContext;
                }
            }

            Message message = Message.CreateOutcomingMessage(iTransportContext, msg, requestHeaders, requestStream, true);

            try
            {
                message.Recipient = iTransportContext.KnownHosts[this._recipientUri];

                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.ProcessMessage",
                                                             LogMessageType.MessageCreated, null, message, true, message.Recipient,
                                                             this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? message.Stream : null,
                                                             msg.Properties["__Uri"] as string, BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string),
                                                             GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                                                             "Synchronous .NET Remoting invocaiton is being initiated.");

                    message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = msg.Properties["__Uri"] as string;
                    message.ITransportHeaders[Message.TransportHeadersMethodName]       = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageRequestInvoking, null, message, message.Recipient,
                                               null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1, GenuineUtility.TickCount, 0, 0, null, null, null, null,
                                               "The .NET Remoting synchronous invocation has been made.");
                }

                SyncSinkStackResponseProcessor syncSinkStackResponseProcessor = new SyncSinkStackResponseProcessor(iTransportContext, message);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, syncSinkStackResponseProcessor);
                message.CancelSending = syncSinkStackResponseProcessor.IsReceivedEvent;

                try
                {
                    // send the message or initiate the sending
                    iTransportContext.ConnectionManager.Send(message);
                }
                catch (Exception ex)
                {
                    // if it's a response processor's problem, force its exception to be fired
                    if (syncSinkStackResponseProcessor.DispatchedException != null)
                    {
                        throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);
                    }

                    syncSinkStackResponseProcessor.DispatchException(ex);
                    throw;
                }

                if (!GenuineUtility.WaitOne(syncSinkStackResponseProcessor.IsReceivedEvent, GenuineUtility.GetMillisecondsLeft(message.FinishTime)))
                {
                    throw GenuineExceptions.Get_Send_ServerDidNotReply();
                }
                if (syncSinkStackResponseProcessor.DispatchedException != null)
                {
                    throw OperationException.WrapException(syncSinkStackResponseProcessor.DispatchedException);
                }

                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageDispatched, null, syncSinkStackResponseProcessor.Response, syncSinkStackResponseProcessor.Response.Sender,
                                               null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, -1,
                                               GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                               "The .NET Remoting synchronous invocation has been completed.");
                }

                responseHeaders = syncSinkStackResponseProcessor.Response.ITransportHeaders;
                responseStream  = syncSinkStackResponseProcessor.Response.Stream;
            }
            catch (Exception ex)
            {
                // LOG: put down the log record
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.ProcessMessage",
                                               LogMessageType.MessageDispatched, ex, message, message.Recipient, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, null, -1,
                                               GenuineUtility.TickCount, 0, message.SeqNo, null, null, null, null,
                                               "The exception is dispatched to the caller context.");
                }

                throw;
            }
        }
        /// <summary>
        /// Requests asynchronous processing of a method call on the current sink.
        /// </summary>
        /// <param name="sinkStack">A stack of channel sinks that called this sink.</param>
        /// <param name="msg">The message to process.</param>
        /// <param name="headers">The headers to add to the outgoing message heading to the server.</param>
        /// <param name="stream">The stream headed to the transport sink.</param>
        public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg,
                                        ITransportHeaders headers, Stream stream)
        {
            ITransportContext iTransportContext = this.ITransportContext;

            if (!GenuineUtility.CheckUrlOnConnectivity(this._recipientUri))
            {
                // get the transport context from the Uri Storage
                iTransportContext = UriStorage.GetTransportContext(this._recipientUri);
                if (iTransportContext == null)
                {
                    iTransportContext = this.ITransportContext;
                }
            }

            Message message = Message.CreateOutcomingMessage(iTransportContext, msg, headers, stream, false);

            message.Recipient = iTransportContext.KnownHosts[this._recipientUri];
            IMethodMessage iMethodMessage = (IMethodMessage)msg;

            message.IsOneWay = RemotingServices.IsOneWay(iMethodMessage.MethodBase);

            // LOG: put down the log record
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            if (binaryLogWriter != null && binaryLogWriter[LogCategory.MessageProcessing] > 0)
            {
                binaryLogWriter.WriteMessageCreatedEvent("GenuineTcpClientTransportSink.AsyncProcessRequest",
                                                         LogMessageType.MessageCreated, null, message, true, message.Recipient,
                                                         this.ITransportContext.BinaryLogWriter[LogCategory.MessageProcessing] > 1 ? message.Stream : null,
                                                         msg.Properties["__Uri"] as string, BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string),
                                                         GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, null, -1, -1, null, -1, null,
                                                         "Asynchronous .NET Remoting invocaiton is being initiated.");

                message.ITransportHeaders[Message.TransportHeadersInvocationTarget] = msg.Properties["__Uri"] as string;
                message.ITransportHeaders[Message.TransportHeadersMethodName]       = BinaryLogWriter.ParseInvocationMethod(msg.Properties["__MethodName"] as string, msg.Properties["__TypeName"] as string);

                binaryLogWriter.WriteEvent(LogCategory.MessageProcessing, "GenuineTcpClientTransportSink.AsyncProcessRequest",
                                           LogMessageType.MessageRequestInvoking, null, message, message.Recipient,
                                           null,
                                           GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                           null, null, -1,
                                           GenuineUtility.TickCount, 0, 0, null, null, null, null,
                                           "The .NET Remoting asynchronous invocation is being initiated.");
            }

            // register the response handler
            AsyncSinkStackResponseProcessor asyncSinkStackResponseProcessor = null;

            if (!message.IsOneWay)
            {
                asyncSinkStackResponseProcessor = new AsyncSinkStackResponseProcessor(iTransportContext, message, sinkStack);
                iTransportContext.IIncomingStreamHandler.RegisterResponseProcessor(message.MessageId, asyncSinkStackResponseProcessor);
            }

            try
            {
                // and try to send the message
                iTransportContext.ConnectionManager.Send(message);
            }
            catch (Exception ex)
            {
                asyncSinkStackResponseProcessor.DispatchException(ex);
                throw;
            }
        }