/// <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); }
/// <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."); } } } }
/// <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(); } } }
/// <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; } }