public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, Stream stream) { // headers, stream are null, because formatting is first sink to create these two AsyncServerProcessingData asyncData = (AsyncServerProcessingData)state; try { IMessage requestMsg = asyncData.RequestMsg; SerialiseResponse(sinkStack, requestMsg, asyncData.ServerCon, msg, ref headers, out stream); } catch (Exception e) { if (asyncData.RequestMsg is IMethodCallMessage) { msg = new ReturnMessage(e, (IMethodCallMessage)asyncData.RequestMsg); } else { msg = new ReturnMessage(e, null); // no useful information present for requestMsg } // serialise the exception SerialiseExceptionResponse(sinkStack, (IMessage)state, asyncData.ServerCon, msg, ref headers, out stream); } sinkStack.AsyncProcessResponse(msg, headers, stream); // pass further on to the stream handling sinks }
/// <summary> /// process a giop request message. /// </summary> private ServerProcessing ProcessRequestMessage(IServerChannelSinkStack sinkStack, ITransportHeaders requestHeaders, CdrMessageInputStream msgInput, GiopServerConnection serverCon, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { IMessage deserReqMsg = null; responseHeaders = null; try { try { // deserialise the request deserReqMsg = m_messageHandler.ParseIncomingRequestMessage(msgInput, serverCon.ConDesc); } finally { //request deserialised -> safe to read next request while processing request in servant // (or sending request deserialisation exception) try { serverCon.NotifyDeserialiseRequestComplete(); } catch (Exception ne) { // unexpected exception. Abort message processing, problem with transport. throw new NotifyReadRequestException("Problem while trying to inform transport about request deserialistion.", ne); } } // processing may be done asynchronous, therefore push this sink on the stack to process a response async AsyncServerProcessingData asyncData = new AsyncServerProcessingData(deserReqMsg, serverCon); sinkStack.Push(this, asyncData); ServerProcessing processingResult; try { // forward the call to the next message handling sink processingResult = m_nextSink.ProcessMessage(sinkStack, deserReqMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream); } catch (Exception) { sinkStack.Pop(this); throw; } switch (processingResult) { case ServerProcessing.Complete: sinkStack.Pop(this); // not async // send the response SerialiseResponse(sinkStack, deserReqMsg, serverCon, responseMsg, ref responseHeaders, out responseStream); break; case ServerProcessing.Async: sinkStack.Store(this, asyncData); // this sink want's to process async response break; case ServerProcessing.OneWay: // nothing to do, because no response expected sinkStack.Pop(this); break; } return(processingResult); } catch (MessageHandling.RequestDeserializationException deserEx) { // exception from DeserialisRequest responseMsg = deserEx.ResponseMessage; // an exception was thrown during deserialization SerialiseExceptionResponse(sinkStack, deserEx.RequestMessage, serverCon, responseMsg, ref responseHeaders, out responseStream); return(ServerProcessing.Complete); } catch (NotifyReadRequestException nrre) { Trace.WriteLine("Failed to inform transport about request deserialisation. Processing problem on server connection after unexpected exception: " + nrre.InnerException); throw nrre; } catch (Exception e) { // serialise an exception response if (deserReqMsg != null) { if (deserReqMsg is IMethodCallMessage) { responseMsg = new ReturnMessage(e, (IMethodCallMessage)deserReqMsg); } else { responseMsg = new ReturnMessage(e, null); // no usable information present } SerialiseExceptionResponse(sinkStack, deserReqMsg, serverCon, responseMsg, ref responseHeaders, out responseStream); } else { throw e; } return(ServerProcessing.Complete); // send back an error msg } }
/// <summary> /// process a giop request message. /// </summary> private ServerProcessing ProcessRequestMessage(IServerChannelSinkStack sinkStack, ITransportHeaders requestHeaders, CdrMessageInputStream msgInput, GiopServerConnection serverCon, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { IMessage deserReqMsg = null; responseHeaders = null; try { try { // deserialise the request deserReqMsg = m_messageHandler.ParseIncomingRequestMessage(msgInput, serverCon.ConDesc); } finally { //request deserialised -> safe to read next request while processing request in servant // (or sending request deserialisation exception) try { serverCon.NotifyDeserialiseRequestComplete(); } catch (Exception ne) { // unexpected exception. Abort message processing, problem with transport. throw new NotifyReadRequestException("Problem while trying to inform transport about request deserialistion.", ne); } } // processing may be done asynchronous, therefore push this sink on the stack to process a response async AsyncServerProcessingData asyncData = new AsyncServerProcessingData(deserReqMsg, serverCon); sinkStack.Push(this, asyncData); ServerProcessing processingResult; try { // forward the call to the next message handling sink processingResult = m_nextSink.ProcessMessage(sinkStack, deserReqMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream); } catch (Exception) { sinkStack.Pop(this); throw; } switch (processingResult) { case ServerProcessing.Complete: sinkStack.Pop(this); // not async // send the response SerialiseResponse(sinkStack, deserReqMsg, serverCon, responseMsg, ref responseHeaders, out responseStream); break; case ServerProcessing.Async: sinkStack.Store(this, asyncData); // this sink want's to process async response break; case ServerProcessing.OneWay: // nothing to do, because no response expected sinkStack.Pop(this); break; } return processingResult; } catch (MessageHandling.RequestDeserializationException deserEx) { // exception from DeserialisRequest responseMsg = deserEx.ResponseMessage; // an exception was thrown during deserialization SerialiseExceptionResponse(sinkStack, deserEx.RequestMessage, serverCon, responseMsg, ref responseHeaders, out responseStream); return ServerProcessing.Complete; } catch (NotifyReadRequestException nrre) { Trace.WriteLine("Failed to inform transport about request deserialisation. Processing problem on server connection after unexpected exception: " + nrre.InnerException); throw nrre; } catch (Exception e) { // serialise an exception response if (deserReqMsg != null) { if (deserReqMsg is IMethodCallMessage) { responseMsg = new ReturnMessage(e, (IMethodCallMessage) deserReqMsg); } else { responseMsg = new ReturnMessage(e, null); // no usable information present } SerialiseExceptionResponse(sinkStack, deserReqMsg, serverCon, responseMsg, ref responseHeaders, out responseStream); } else { throw e; } return ServerProcessing.Complete; // send back an error msg } }