internal IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink, String receiver) { IMessage desResMsg = null; bool fAdded = true; String seqNum = null; try { // // Create a new wait object which will wait for the // response to arrive // if (null != replySink) { WaitObject obj = new WaitObject(msg, replySink); seqNum = GetNextSequenceNumber(); m_hashTable.Add(seqNum, obj); fAdded = true; } SendMessage(msg, receiver, seqNum); // Note: The response will be deliverd to the OnArrival method // which is responsible for notifying the sink. } catch (Exception e) { InternalRemotingServices.RemotingTrace("SmtpChannel::AsyncProcessMessage threw exception " + e.StackTrace); try { // Cleanup state if (fAdded) { m_hashTable.Remove(seqNum); } // Notify the sink if (null != replySink) { // Create a message which encapsulates an exception desResMsg = new ReturnMessage(e, null); replySink.SyncProcessMessage(desResMsg); } } catch (Exception) { // Fatal error.. return null } } return(null); }
void ProcessResponse(ISmtpMessage smtpMessage, String contentType, String seqNum, MemoryStream stm) { InternalRemotingServices.RemotingTrace("Received response"); // Notify the waiting object that its response // has arrived WaitObject obj = (WaitObject)m_hashTable[seqNum]; if (null != obj) { InternalRemotingServices.RemotingTrace("Found an object waiting"); // First remove the object in a threadsafe manner // so that we do not deliver the response twice // due to duplicate replies or other errors from // Smtp lock (obj) { if (m_hashTable.Contains(seqNum)) { InternalRemotingServices.RemotingTrace("Found an object to notify"); m_hashTable.Remove(seqNum); IMethodCallMessage request = (IMethodCallMessage)obj.Request; Header[] h = new Header[3]; h[0] = new Header("__TypeName", request.TypeName); h[1] = new Header("__MethodName", request.MethodName); h[2] = new Header("__MethodSignature", request.MethodSignature); IMessage response = CoreChannel.DeserializeMessage(contentType, stm, false, request, h); InternalRemotingServices.RemotingTrace("Deserialized message"); if (response == null) { throw new Exception(CoreChannel.GetResourceString("Remoting_DeserializeMessage")); } // Notify the object obj.Notify(response); } } } else { InternalRemotingServices.RemotingTrace("No object waiting"); } }
IMessage ReceiveMessage(WaitObject obj) { IMessage desResMsg = null; InternalRemotingServices.RemotingTrace("SmtpChannel::RecieveMessage IN"); lock (obj) { if (obj.ShouldWait) { InternalRemotingServices.RemotingTrace("ReceiveMessage Staring wait..."); // This will release the lock and wait till the // receiving thread signals it Monitor.Wait(obj); } // Extract the response object which is set by the // thread which received the response desResMsg = obj.Response; } InternalRemotingServices.RemotingTrace("Received message"); return(desResMsg); }
// Internal methods internal IMessage SyncProcessMessage(IMessage reqMsg, String receiver) { IMessage desResMsg = null; bool fAdded = true; String seqNum = null; try { InternalRemotingServices.RemotingTrace("SmtpChannel::SyncProcessMessage"); // HACKALERT:: // we are going to temporarily not send the call context Object callContext = reqMsg.Properties["__CallContext"]; if (callContext != null) { reqMsg.Properties["__CallContext"] = null; } // // Create a new wait object which will wait for the // response to arrive // WaitObject obj = new WaitObject(reqMsg, null); seqNum = GetNextSequenceNumber(); m_hashTable.Add(seqNum, obj); fAdded = true; // // Serialize the message and send it using Smtp // SendMessage(reqMsg, receiver, seqNum); // // Receive server response // InternalRemotingServices.RemotingTrace("SmtpMessageSink::SyncProcessMessage before ReceiveResponse"); desResMsg = ReceiveMessage(obj); if (callContext != null) { desResMsg.Properties["__CallContext"] = callContext; } InternalRemotingServices.RemotingTrace("SmtpChannel::Returning successfully from SyncProcessMessage"); } catch (Exception e) { InternalRemotingServices.RemotingTrace("SmtpChannel::SyncProcessMessage threw exception " + e.StackTrace); try { if (fAdded) { m_hashTable.Remove(seqNum); } desResMsg = new ReturnMessage(e, null); } catch (Exception) { // Fatal error.. return null } } return(desResMsg); }