BinaryFormatterSinks.cs

本文介绍了一个用于.NET平台的二进制序列化客户端和服务端处理机制,包括了如何通过二进制格式传输对象,以及客户端和服务端如何进行消息的序列化和反序列化过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. // ==++==
  2. // 
  3. //   
  4. //    Copyright (c) 2002 Microsoft Corporation.  All rights reserved.
  5. //   
  6. //    The use and distribution terms for this software are contained in the file
  7. //    named license.txt, which can be found in the root of this distribution.
  8. //    By using this software in any fashion, you are agreeing to be bound by the
  9. //    terms of this license.
  10. //   
  11. //    You must not remove this notice, or any other, from this software.
  12. //   
  13. // 
  14. // ==--==
  15. //==========================================================================
  16. //  File:       BinaryFormatterSinks.cs
  17. //
  18. //  Summary:    Binary formatter client and server sinks.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.Collections;
  23. using System.IO;
  24. using System.Reflection;
  25. using System.Runtime.Remoting;
  26. using System.Runtime.Remoting.Channels;
  27. using System.Runtime.Remoting.Channels.Http;
  28. using System.Runtime.Remoting.Messaging;
  29. using System.Runtime.Remoting.Metadata;
  30. using System.Globalization;
  31. namespace System.Runtime.Remoting.Channels
  32. {
  33.     //
  34.     // CLIENT-SIDE BINARY FORMATTER SINKS
  35.     //
  36.     /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSinkProvider"]/*' />
  37.     public class BinaryClientFormatterSinkProvider : IClientFormatterSinkProvider
  38.     {
  39.         private IClientChannelSinkProvider _next;
  40.         // settings from config
  41.         private bool _includeVersioning = true;
  42.         private bool _strictBinding = false;
  43.         
  44.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSinkProvider.BinaryClientFormatterSinkProvider"]/*' />
  45.         public BinaryClientFormatterSinkProvider()
  46.         {
  47.         } // BinaryClientFormatterSinkProvider
  48.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSinkProvider.BinaryClientFormatterSinkProvider1"]/*' />
  49.         public BinaryClientFormatterSinkProvider(IDictionary properties, ICollection providerData)
  50.         {
  51.             // look at properties
  52.             if (properties != null)
  53.             {
  54.                 foreach (DictionaryEntry entry in properties)
  55.                 {
  56.                     String keyStr = entry.Key.ToString();
  57.                     switch (keyStr)
  58.                     {
  59.                     case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value); break;
  60.                     case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value); break;
  61.                     default:
  62.                         CoreChannel.ReportUnknownProviderConfigProperty(
  63.                             this.GetType().Name, keyStr);
  64.                         break;
  65.                     }
  66.                 }
  67.             }
  68.         
  69.             // not expecting any provider data
  70.             CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData);
  71.         } // BinaryClientFormatterSinkProvider
  72.    
  73.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSinkProvider.CreateSink"]/*' />
  74.         public IClientChannelSink CreateSink(IChannelSender channel, String url, 
  75.                                              Object remoteChannelData)
  76.         {
  77.             IClientChannelSink nextSink = null;
  78.             if (_next != null)
  79.             {
  80.                 nextSink = _next.CreateSink(channel, url, remoteChannelData);
  81.                 if (nextSink == null)
  82.                     return null;
  83.             }
  84.             SinkChannelProtocol protocol = CoreChannel.DetermineChannelProtocol(channel);
  85.             BinaryClientFormatterSink sink = new BinaryClientFormatterSink(nextSink);
  86.             sink.IncludeVersioning = _includeVersioning;
  87.             sink.StrictBinding = _strictBinding;
  88.             sink.ChannelProtocol = protocol;
  89.             return sink;
  90.         } // CreateSink
  91.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSinkProvider.Next"]/*' />
  92.         public IClientChannelSinkProvider Next
  93.         {
  94.             get { return _next; }
  95.             set { _next = value; }
  96.         }
  97.     } // class BinaryClientFormatterSinkProvider
  98.     
  99.     /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink"]/*' />
  100.     public class BinaryClientFormatterSink : IClientFormatterSink
  101.     {
  102.         private IClientChannelSink _nextSink = null;
  103.         private bool _includeVersioning = true// should versioning be used
  104.         private bool _strictBinding = false// strict binding should be used
  105.         
  106.         private SinkChannelProtocol _channelProtocol = SinkChannelProtocol.Other;
  107.         
  108.     
  109.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.BinaryClientFormatterSink"]/*' />
  110.         public BinaryClientFormatterSink(IClientChannelSink nextSink)
  111.         {
  112.             _nextSink = nextSink;
  113.         } // BinaryClientFormatterSink
  114.         internal bool IncludeVersioning
  115.         {
  116.             set { _includeVersioning = value; }
  117.         } // IncludeVersioning
  118.         internal bool StrictBinding
  119.         {
  120.             set { _strictBinding = value; }
  121.         } // StrictBinding
  122.         internal SinkChannelProtocol ChannelProtocol
  123.         {
  124.             set { _channelProtocol = value; }
  125.         } // ChannelProtocol
  126.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.NextSink"]/*' />
  127.         public IMessageSink NextSink { get { throw new NotSupportedException(); } }
  128.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.SyncProcessMessage"]/*' />
  129.         public IMessage SyncProcessMessage(IMessage msg)
  130.         {
  131.             IMethodCallMessage mcm = msg as IMethodCallMessage;
  132.             IMessage retMsg;
  133.         
  134.             try 
  135.             {
  136.                 // serialize message
  137.                 ITransportHeaders headers;
  138.                 Stream requestStream;
  139.                 RemotingServices.LogRemotingStage(CoreChannel.CLIENT_MSG_SER);
  140.                 SerializeMessage(msg, out headers, out requestStream);
  141.                 RemotingServices.LogRemotingStage(CoreChannel.CLIENT_MSG_SEND);
  142.             
  143.                 // process message
  144.                 Stream returnStream;
  145.                 ITransportHeaders returnHeaders;
  146.                 _nextSink.ProcessMessage(msg, headers, requestStream,
  147.                                          out returnHeaders, out returnStream);
  148.                 if (returnHeaders == null)
  149.                     throw new ArgumentNullException("returnHeaders");                                         
  150.                                      
  151.                 // deserialize stream
  152.                 RemotingServices.LogRemotingStage(CoreChannel.CLIENT_RET_DESER);
  153.                 retMsg = DeserializeMessage(mcm, returnHeaders, returnStream);
  154.             }
  155.             catch (Exception e)
  156.             {
  157.                 retMsg = new ReturnMessage(e, mcm);
  158.             }
  159.             
  160.             RemotingServices.LogRemotingStage(CoreChannel.CLIENT_RET_SINK_CHAIN);
  161.             return retMsg;
  162.         } // SyncProcessMessage
  163.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.AsyncProcessMessage"]/*' />
  164.         public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  165.         {
  166.             IMethodCallMessage mcm = (IMethodCallMessage)msg;
  167.             IMessage retMsg;
  168.             try
  169.             {
  170.                 // serialize message
  171.                 ITransportHeaders headers;
  172.                 Stream requestStream;
  173.                 SerializeMessage(msg, out headers, out requestStream);
  174.             
  175.                 // process message
  176.                 ClientChannelSinkStack sinkStack = new ClientChannelSinkStack(replySink);
  177.                 sinkStack.Push(this, msg);
  178.                 _nextSink.AsyncProcessRequest(sinkStack, msg, headers, requestStream);
  179.             }
  180.             catch (Exception e)
  181.             {
  182.                 retMsg = new ReturnMessage(e, mcm);
  183.                 if (replySink != null)
  184.                     replySink.SyncProcessMessage(retMsg);
  185.             }
  186.                                           
  187.             return null;
  188.         } // AsyncProcessMessage
  189.         // helper function to serialize the message
  190.         private void SerializeMessage(IMessage msg, 
  191.                                       out ITransportHeaders headers, out Stream stream)
  192.         {
  193.             BaseTransportHeaders requestHeaders = new BaseTransportHeaders();
  194.             headers = requestHeaders;
  195.             // add other http soap headers
  196.             requestHeaders.ContentType = CoreChannel.BinaryMimeType;
  197.             if (_channelProtocol == SinkChannelProtocol.Http)
  198.                 headers["__RequestVerb"] = "POST";
  199.             bool bMemStream = false;
  200.             stream = _nextSink.GetRequestStream(msg, headers);
  201.             if (stream == null)
  202.             {
  203.                 stream = new ChunkedMemoryStream(CoreChannel.BufferPool);
  204.                 bMemStream = true;
  205.             }
  206.             CoreChannel.SerializeBinaryMessage(msg, stream, _includeVersioning);
  207.             if (bMemStream)
  208.                 stream.Position = 0;               
  209.         } // SerializeMessage
  210.         // helper function to deserialize the message
  211.         private IMessage DeserializeMessage(IMethodCallMessage mcm, 
  212.                                             ITransportHeaders headers, Stream stream)
  213.         {
  214.             // deserialize the message
  215.             IMessage retMsg = CoreChannel.DeserializeBinaryResponseMessage(stream, mcm, _strictBinding); 
  216.                 
  217.             stream.Close();
  218.             return retMsg;
  219.         } // DeserializeMessage
  220.        
  221.         //
  222.         // IClientChannelSink implementation
  223.         //
  224.         
  225.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.ProcessMessage"]/*' />
  226.         public void ProcessMessage(IMessage msg,
  227.                                    ITransportHeaders requestHeaders, Stream requestStream,
  228.                                    out ITransportHeaders responseHeaders, out Stream responseStream)
  229.         {
  230.             // should never gets called, since this sink is always first
  231.             throw new NotSupportedException();
  232.         } // ProcessMessage
  233.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.AsyncProcessRequest"]/*' />
  234.         public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg,
  235.                                         ITransportHeaders headers, Stream stream)
  236.         {
  237.             // should never be called, this sink is always first
  238.             throw new NotSupportedException();
  239.         } // AsyncProcessRequest
  240.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.AsyncProcessResponse"]/*' />
  241.         public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, Object state,
  242.                                          ITransportHeaders headers, Stream stream)
  243.         {
  244.             // previously we stored the outgoing message in state
  245.             IMethodCallMessage mcm = (IMethodCallMessage)state;  
  246.             IMessage retMsg = DeserializeMessage(mcm, headers, stream);
  247.             sinkStack.DispatchReplyMessage(retMsg);
  248.         } // AsyncProcessRequest
  249.        
  250.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.GetRequestStream"]/*' />
  251.         public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
  252.         {
  253.             // never called on formatter sender sink
  254.             throw new NotSupportedException();
  255.         }
  256.         
  257.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.NextChannelSink"]/*' />
  258.         public IClientChannelSink NextChannelSink
  259.         {
  260.             get { return _nextSink; }
  261.         }
  262.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryClientFormatterSink.Properties"]/*' />
  263.         public IDictionary Properties
  264.         {
  265.             get { return null; }
  266.         } // Properties
  267.         //
  268.         // end of IClientChannelSink implementation
  269.         //
  270.         
  271.     } // class BinaryClientFormatterSink
  272.     //
  273.     // SERVER-SIDE SOAP FORMATTER SINKS
  274.     //
  275.     /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider"]/*' />
  276.     public class BinaryServerFormatterSinkProvider : IServerFormatterSinkProvider
  277.     {
  278.         private IServerChannelSinkProvider _next = null;
  279.         // settings from config
  280.         private bool _includeVersioning = true;
  281.         private bool _strictBinding = false;
  282.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider.BinaryServerFormatterSinkProvider"]/*' />
  283.         public BinaryServerFormatterSinkProvider()
  284.         {
  285.         } // BinaryServerFormatterSinkProvider
  286.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider.BinaryServerFormatterSinkProvider1"]/*' />
  287.         public BinaryServerFormatterSinkProvider(IDictionary properties, ICollection providerData)
  288.         {       
  289.             // look at properties
  290.             if (properties != null)
  291.             {
  292.                 foreach (DictionaryEntry entry in properties)
  293.                 {
  294.                     String keyStr = entry.Key.ToString();
  295.                     switch (keyStr)
  296.                     {
  297.                     case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value); break;
  298.                     case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value); break;
  299.                     default:
  300.                         CoreChannel.ReportUnknownProviderConfigProperty(
  301.                             this.GetType().Name, keyStr);
  302.                         break;
  303.                     }
  304.                 }
  305.             }
  306.         
  307.             // not expecting any provider data
  308.             CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData);        
  309.         } // BinaryServerFormatterSinkProvider
  310.         
  311.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider.GetChannelData"]/*' />
  312.         public void GetChannelData(IChannelDataStore channelData)
  313.         {
  314.         } // GetChannelData
  315.    
  316.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider.CreateSink"]/*' />
  317.         public IServerChannelSink CreateSink(IChannelReceiver channel)
  318.         {
  319.             if(null == channel)
  320.             {
  321.                 throw new ArgumentNullException("channel");               
  322.             }
  323.             IServerChannelSink nextSink = null;
  324.             if (_next != null)
  325.                 nextSink = _next.CreateSink(channel);
  326.             BinaryServerFormatterSink.Protocol protocol = 
  327.                 BinaryServerFormatterSink.Protocol.Other;
  328.             // see if this is an http channel
  329.             String uri = channel.GetUrlsForUri("")[0];
  330.             if (String.Compare("http", 0, uri, 0, 4, true, CultureInfo.InvariantCulture) == 0)
  331.                 protocol = BinaryServerFormatterSink.Protocol.Http;            
  332.             BinaryServerFormatterSink sink = new BinaryServerFormatterSink(protocol, nextSink, channel);
  333.             sink.IncludeVersioning = _includeVersioning;
  334.             sink.StrictBinding = _strictBinding;
  335.             return sink;
  336.         } // CreateSink
  337.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSinkProvider.Next"]/*' />
  338.         public IServerChannelSinkProvider Next
  339.         {
  340.             get { return _next; }
  341.             set { _next = value; }
  342.         } // Next
  343.         
  344.     } // class BinaryServerFormatterSinkProvider
  345.     
  346.     /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink"]/*' />
  347.     public class BinaryServerFormatterSink : IServerChannelSink
  348.     {
  349.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="Protocol"]/*' />
  350.         [Serializable]
  351.         public enum Protocol
  352.         {
  353.             /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="Protocol.Http"]/*' />
  354.             Http, // special processing needed for http
  355.             /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="Protocol.Other"]/*' />
  356.             Other
  357.         }
  358.     
  359.         private IServerChannelSink _nextSink; // If this sink doesn't recognize, the incoming
  360.                                               //   format then it should call the next
  361.                                               //   sink if there is one.
  362.         private Protocol _protocol; // remembers which protocol is being used
  363.         
  364.         private IChannelReceiver _receiver; // transport sink used to parse url
  365.         private bool _includeVersioning = true// should versioning be used
  366.         private bool _strictBinding = false// strict binding should be used
  367.                 
  368.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.BinaryServerFormatterSink"]/*' />
  369.         public BinaryServerFormatterSink(Protocol protocol, IServerChannelSink nextSink,
  370.                                          IChannelReceiver receiver)
  371.         {
  372.             if (receiver == null)
  373.                 throw new ArgumentNullException("receiver");
  374.             _nextSink = nextSink;
  375.             _protocol = protocol;
  376.             _receiver = receiver;            
  377.         } // BinaryServerFormatterSinkProvider
  378.         internal bool IncludeVersioning
  379.         {
  380.             set { _includeVersioning = value; }
  381.         } // IncludeVersioning
  382.         internal bool StrictBinding
  383.         {
  384.             set { _strictBinding = value; }
  385.         } // StrictBinding
  386.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.ProcessMessage"]/*' />
  387.         public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack,
  388.             IMessage requestMsg,
  389.             ITransportHeaders requestHeaders, Stream requestStream,
  390.             out IMessage responseMsg, out ITransportHeaders responseHeaders, 
  391.             out Stream responseStream)
  392.         {
  393.             if (requestMsg != null)
  394.             {
  395.                 // The message has already been deserialized so delegate to the next sink.
  396.                 return _nextSink.ProcessMessage(
  397.                     sinkStack,
  398.                     requestMsg, requestHeaders, requestStream, 
  399.                     out responseMsg, out responseHeaders, out responseStream);
  400.             }
  401.         
  402.             if (requestHeaders ==  null)
  403.                 throw new ArgumentNullException("requestHeaders");
  404.             BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders;
  405.         
  406.             ServerProcessing processing;
  407.         
  408.             responseHeaders = null;
  409.             responseStream = null;
  410.             String verb = null;
  411.             String contentType = null;
  412.             bool bCanServiceRequest = true;
  413.             // determine the content type
  414.             String contentTypeHeader = null;
  415.             if (wkRequestHeaders != null)
  416.                 contentTypeHeader = wkRequestHeaders.ContentType;
  417.             else
  418.                 contentTypeHeader = requestHeaders["Content-Type"as String;
  419.             if (contentTypeHeader != null)
  420.             {
  421.                 String charsetValue;
  422.                 HttpChannelHelper.ParseContentType(contentTypeHeader,
  423.                                                    out contentType, out charsetValue);
  424.             }
  425.             // check to see if Content-Type matches
  426.             if ((contentType != null) &
  427.                 (String.CompareOrdinal(contentType, CoreChannel.BinaryMimeType) != 0))
  428.             {
  429.                 bCanServiceRequest = false;                
  430.             }
  431.             // check for http specific verbs
  432.             if (_protocol == Protocol.Http)
  433.             {
  434.                 verb = (String)requestHeaders["__RequestVerb"];    
  435.                 if (!verb.Equals("POST") && !verb.Equals("M-POST"))
  436.                     bCanServiceRequest = false;
  437.             }
  438.             // either delegate or return an error message if we can't service the request
  439.             if (!bCanServiceRequest)
  440.             {
  441.                 // delegate to next sink if available
  442.                 if (_nextSink != null)
  443.                 {
  444.                     return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream,   
  445.                         out responseMsg, out responseHeaders, out responseStream);
  446.                 }
  447.                 else
  448.                 {
  449.                     // send back an error message
  450.                     if (_protocol == Protocol.Http)
  451.                     {
  452.                         // return a client bad request error     
  453.                         responseHeaders = new TransportHeaders();
  454.                         responseHeaders["__HttpStatusCode"] = "400";
  455.                         responseHeaders["__HttpReasonPhrase"] = "Bad Request";
  456.                         responseStream = null;
  457.                         responseMsg = null;
  458.                         return ServerProcessing.Complete;
  459.                     }
  460.                     else
  461.                     {
  462.                         // The transport sink will catch this and do something here.
  463.                         throw new RemotingException(
  464.                             CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat"));
  465.                     }
  466.                 }
  467.             }
  468.             
  469.             try
  470.             {
  471.                 String objectUri = null;
  472.                 if (wkRequestHeaders != null)
  473.                     objectUri = wkRequestHeaders.RequestUri;
  474.                 else
  475.                     objectUri = (String)requestHeaders[CommonTransportKeys.RequestUri];              
  476.             
  477.                 if (RemotingServices.GetServerTypeForUri(objectUri) == null)
  478.                     throw new RemotingException(
  479.                         CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished"));
  480.                 RemotingServices.LogRemotingStage(CoreChannel.SERVER_MSG_DESER);
  481.                 // Deserialize Request - Stream to IMessage
  482.                 requestMsg =
  483.                     CoreChannel.DeserializeBinaryRequestMessage(objectUri, requestStream, _strictBinding);
  484.                 requestStream.Close();
  485.                 if(requestMsg == null)
  486.                 {
  487.                     throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage"));
  488.                 }
  489.                 
  490.                 // Dispatch Call
  491.                 sinkStack.Push(thisnull);
  492.                 RemotingServices.LogRemotingStage(CoreChannel.SERVER_MSG_SINK_CHAIN);
  493.                 processing =                    
  494.                     _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null,
  495.                         out responseMsg, out responseHeaders, out responseStream);
  496.                 // make sure that responseStream is null
  497.                 if (responseStream != null)
  498.                 {
  499.                     throw new RemotingException(
  500.                         CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream"));
  501.                 }
  502.                 
  503.                 switch (processing)
  504.                 {
  505.                 case ServerProcessing.Complete:
  506.                 {
  507.                     if (responseMsg == null)
  508.                         throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage"));
  509.                     sinkStack.Pop(this);
  510.                     RemotingServices.LogRemotingStage(CoreChannel.SERVER_RET_SER);
  511.                     SerializeResponse(sinkStack, responseMsg, 
  512.                                       ref responseHeaders, out responseStream);
  513.                     break;
  514.                 } // case ServerProcessing.Complete
  515.                 case ServerProcessing.OneWay:
  516.                 {
  517.                     sinkStack.Pop(this);
  518.                     break;
  519.                 } // case ServerProcessing.OneWay:
  520.                 case ServerProcessing.Async:
  521.                 {
  522.                     sinkStack.Store(thisnull);
  523.                     break;   
  524.                 } // case ServerProcessing.Async
  525.                     
  526.                 } // switch (processing)                
  527.             }
  528.             catch(Exception e)
  529.             {
  530.                 processing = ServerProcessing.Complete;
  531.                 responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg));
  532.                 responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
  533.                 responseStream.Position = 0;
  534.                 responseHeaders = new TransportHeaders();
  535.                 if (_protocol == Protocol.Http)
  536.                 {
  537.                     responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
  538.                 }
  539.             }
  540.             RemotingServices.LogRemotingStage(CoreChannel.SERVER_RET_SEND);
  541.             return processing;
  542.         } // ProcessMessage
  543.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.AsyncProcessResponse"]/*' />
  544.         public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state,
  545.                                          IMessage msg, ITransportHeaders headers, Stream stream)
  546.         {
  547.             SerializeResponse(sinkStack, msg, ref headers, out stream);
  548.             sinkStack.AsyncProcessResponse(msg, headers, stream);
  549.         } // AsyncProcessResponse
  550.         private void SerializeResponse(IServerResponseChannelSinkStack sinkStack,
  551.                                        IMessage msg, ref ITransportHeaders headers,
  552.                                        out Stream stream)
  553.         {
  554.             BaseTransportHeaders responseHeaders = new BaseTransportHeaders();
  555.             if (headers != null)
  556.             {
  557.                 // copy old headers into new headers
  558.                 foreach (DictionaryEntry entry in headers)
  559.                 {
  560.                     responseHeaders[entry.Key] = entry.Value;
  561.                 }
  562.             }            
  563.             headers = responseHeaders;
  564.             if (_protocol == Protocol.Http)
  565.             {
  566.                 responseHeaders.ContentType = CoreChannel.BinaryMimeType;
  567.             }
  568.             bool bMemStream = false;
  569.             stream = sinkStack.GetResponseStream(msg, headers);
  570.             if (stream == null)
  571.             {
  572.                 stream = new ChunkedMemoryStream(CoreChannel.BufferPool);
  573.                 bMemStream = true;
  574.             }
  575.             bool bBashUrl = CoreChannel.SetupUrlBashingForIisSslIfNecessary(); 
  576.             try
  577.             {
  578.                 CoreChannel.SerializeBinaryMessage(msg, stream, _includeVersioning);
  579.             }
  580.             finally
  581.             {
  582.                 CoreChannel.CleanupUrlBashingForIisSslIfNecessary(bBashUrl);
  583.             }
  584.             if (bMemStream)            
  585.                 stream.Position = 0;
  586.         } // SerializeResponse
  587.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.GetResponseStream"]/*' />
  588.         public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state,
  589.                                         IMessage msg, ITransportHeaders headers)
  590.         {
  591.             // This should never get called since we're the last in the chain, and never
  592.             //   push ourselves to the sink stack.
  593.             throw new NotSupportedException();
  594.         } // GetResponseStream
  595.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.NextChannelSink"]/*' />
  596.         public IServerChannelSink NextChannelSink
  597.         {
  598.             get { return _nextSink; }
  599.         }
  600.         /// <include file='doc/BinaryFormatterSinks.uex' path='docs/doc[@for="BinaryServerFormatterSink.Properties"]/*' />
  601.         public IDictionary Properties
  602.         {
  603.             get { return null; }
  604.         } // Properties
  605.         
  606.         
  607.     } // class BinaryServerFormatterSink
  608. // namespace System.Runtime.Remoting.Channnels
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值