Vorgehensweise: Aktivieren des StreamingmodusHow to: Enable Streaming

Windows Communication Foundation (WCF)Windows Communication Foundation (WCF) kann Nachrichten entweder unter Verwendung des gepufferten Übertragungsmodus oder des Streamingmodus senden. can send messages using either buffered or streamed transfers. Im voreingestellten gepufferten Übertragungsmodus müssen Nachrichten vollständig übertragen worden sein, bevor sie vom Empfänger gelesen werden können.In the default buffered-transfer mode, a message must be completely delivered before a receiver can read it. Im Streamingmodus kann der Empfänger mit der Verarbeitung der Nachricht beginnen, bevor diese vollständig übertragen wurde.In streaming transfer mode, the receiver can begin to process the message before it is completely delivered. Der Streamingmodus ist hilfreich, wenn die zu übergebenden Informationen sehr umfangreich sind und hintereinander verarbeitet werden können.The streaming mode is useful when the information that is passed is lengthy and can be processed serially. Der Streamingmodus ist auch dann nützlich, wenn eine Nachricht zu groß ist, um als Ganzes gepuffert zu werden.Streaming mode is also useful when the message is too large to be entirely buffered.

Um den Streamingmodus zu aktivieren, definieren Sie den OperationContract angemessen, und aktivieren Sie den Streamingmodus auf Transportebene.To enable streaming, define the OperationContract appropriately and enable streaming at the transport level.

So werden Daten im Streamingmodus übertragenTo stream data

  1. Damit Daten im Streamingmodus übermittelt werden können, muss der OperationContract für den Dienst zwei Anforderungen erfüllen:To stream data, the OperationContract for the service must satisfy two requirements:

    1. Der Parameter, der die zu übermittelten Daten enthält, muss der einzige Parameter der Methode sein.The parameter that holds the data to be streamed must be the only parameter in the method. Wenn beispielsweise die Eingabenachricht im Streamingmodus übertragen werden soll, muss der Vorgang genau einen Eingabeparameter haben.For example, if the input message is the one to be streamed, the operation must have exactly one input parameter. Ebenso gilt, wenn die Ausgabenachricht im Streamingmodus übertragen werden soll, muss der Vorgang entweder genau einen Ausgabeparameter oder einen Rückgabewert haben.Similarly, if the output message is to be streamed, the operation must have either exactly one output parameter or a return value.

    2. Mindestens einer der Parameter bzw. der Rückgabewert muss vom Typ Stream, Message oder IXmlSerializable seinAt least one of the types of the parameter and return value must be either Stream, Message, or IXmlSerializable.

    Das folgende Beispiel enthält einen Vertrag für im Streamingmodus zu übertragende Daten.The following is an example of a contract for streamed data.

    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IStreamingSample
    {
        [OperationContract]
        Stream GetStream(string data);
        [OperationContract]
        bool UploadStream(Stream stream);
        [OperationContract]
        Stream EchoStream(Stream stream);
        [OperationContract]
        Stream GetReversedStream();
    
    }
    
    <ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
    Public Interface IStreamingSample
        <OperationContract()> _
        Function GetStream(ByVal data As String) As Stream
        <OperationContract()> _
        Function UploadStream(ByVal stream As Stream) As Boolean
        <OperationContract()> _
        Function EchoStream(ByVal stream As Stream) As Stream
        <OperationContract()> _
        Function GetReversedStream() As Stream
    
    End Interface
    

    Der GetStream-Vorgang muss gepufferte Eingabedaten des Typs string erhalten, die dann gepuffert werden, und er gibt einen Stream-Wert zurück, der im Streamingmodus übertragen wird.The GetStream operation receives some buffered input data as a string, which is buffered, and returns a Stream, which is streamed. Umgekehrt akzeptiert UploadStream einen (per Streaming übertragenen) Stream und gibt einen (gepufferten) bool zurück.Conversely UploadStream takes in a Stream (streamed) and returns a bool (buffered). EchoStream akzeptiert und gibt einen Wert des Typs Stream zurück und ist ein Beispiel für einen Vorgang, dessen Eingabe- und Ausgabenachrichten per Streaming übertragen werden.EchoStream takes and returns Stream and is an example of an operation whose input and output messages are both streamed. GetReversedStream akzeptiert keine Eingaben und gibt einen Stream-Wert (im Streamingmodus) zurück.Finally, GetReversedStream takes no inputs and returns a Stream (streamed).

  2. Der Streamingmodus muss für die Bindung aktiviert werden.Streaming must be enabled on the binding. Sie legen eine TransferMode-Eigenschaft fest, für die die folgenden Werte zulässig sind:You set a TransferMode property, which can take one of the following values:

    1. Buffered,Buffered,

    2. Streamed, womit ein Kommunikationsstream in beide Richtungen ermöglicht wird.Streamed, which enables streaming communication in both directions.

    3. StreamedRequest, womit der Streamingmodus lediglich für die Übertragung der Anforderung aktiviert wird.StreamedRequest, which enables streaming the request only.

    4. StreamedResponse, womit der Streamingmodus lediglich für die Übertragung der Antwort aktiviert wird.StreamedResponse, which enables streaming the response only.

    Die BasicHttpBinding-Bindung macht die TransferMode-Eigenschaft für die Bindung verfügbar. Dies gilt ebenso für NetTcpBinding und NetNamedPipeBinding.The BasicHttpBinding exposes the TransferMode property on the binding, as does NetTcpBinding and NetNamedPipeBinding. Die TransferMode-Eigenschaft kann auch für das Transportbindungselement festgelegt und in einer benutzerdefinierten Bindung verwendet werden.The TransferMode property can also be set on the transport binding element and used in a custom binding.

    In den folgenden Beispielen wird gezeigt, wie TransferMode im Code und durch Ändern der Konfigurationsdatei festgelegt wird.The following samples show how to set TransferMode by code and by changing the configuration file. In beiden Beispielen wird zudem die maxReceivedMessageSize-Eigenschaft auf 64&#160;MB festgelegt und damit die maximal zulässige Größe für den Empfang von Nachrichten beschränkt.The samples also both set the maxReceivedMessageSize property to 64 MB, which places a cap on the maximum allowable size of messages on receive. Die Standardeinstellung von maxReceivedMessageSize ist 64 KB, was normalerweise zu niedrig für die Verwendung des Streamingmodus ist.The default maxReceivedMessageSize is 64 KB, which is usually too low for streaming scenarios. Legen Sie diese Größeneinstellung, abhängig von der maximalen Größe der Nachrichten, die von der Anwendung empfangen werden sollen, auf einen geeigneten Wert fest.Set this quota setting as appropriate depending on the maximum size of messages your application expects to receive. Beachten Sie außerdem, dass die maxBufferSize-Einstellung die maximale Puffergröße angibt, und legen Sie diese Eigenschaft auf einen angemessenen Wert fest.Also note that maxBufferSize controls the maximum size that is buffered, and set it appropriately.

    1. Der folgende Ausschnitt aus der Konfiguration des Beispiel zeigt, wie die TransferMode-Eigenschaft für basicHttpBinding und eine benutzerdefinierte HTTP-Bindung auf den Streamingmodus festgelegt wird.The following configuration snippet from the sample shows setting the TransferMode property to streaming on the basicHttpBinding and a custom HTTP binding.

      <basicHttpBinding>
        <binding name="HttpStreaming" maxReceivedMessageSize="67108864"
                 transferMode="Streamed"/>
      </basicHttpBinding>
      <!-- an example customBinding using Http and streaming-->
      <customBinding>
        <binding name="Soap12">
          <textMessageEncoding messageVersion="Soap12WSAddressing10" />
          <httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
        </binding>
      </customBinding>
      
    2. Der folgende Codeausschnitt zeigt, wie die TransferMode-Eigenschaft für basicHttpBinding und eine benutzerdefinierte HTTP-Bindung auf den Streamingmodus festgelegt wird.The following code snippet shows setting the TransferMode property to streaming on the basicHttpBinding and a custom HTTP binding.

      public static Binding CreateStreamingBinding()
      {
          BasicHttpBinding b = new BasicHttpBinding();
          b.TransferMode = TransferMode.Streamed;
          return b;
      }
      
      Public Shared Function CreateStreamingBinding() As Binding
          Dim b As New BasicHttpBinding()
          b.TransferMode = TransferMode.Streamed
          Return b
      End Function
      
    3. Der folgende Codeausschnitt zeigt, wie die TransferMode-Eigenschaft für eine benutzerdefinierte TCP-Bindung auf den Streamingmodus festgelegt wird.The following code snippet shows setting the TransferMode property to streaming on a custom TCP binding.

      public static Binding CreateStreamingBinding()
      {
          TcpTransportBindingElement transport = new TcpTransportBindingElement();
          transport.TransferMode = TransferMode.Streamed;
          BinaryMessageEncodingBindingElement encoder = new BinaryMessageEncodingBindingElement();
          CustomBinding binding = new CustomBinding(encoder, transport);
          return binding;
      }
      
      Public Shared Function CreateStreamingBinding() As Binding
          Dim transport As New TcpTransportBindingElement()
          transport.TransferMode = TransferMode.Streamed
          Dim binding As New CustomBinding(New BinaryMessageEncodingBindingElement(), _
                                           transport)
          Return binding
      End Function
      
  3. Die Vorgänge GetStream, UploadStream und EchoStream sind damit befasst, Daten direkt aus einer Datei zu senden oder empfangene Daten direkt in eine Datei auszugeben.The operations GetStream, UploadStream, and EchoStream all deal with sending data directly from a file or saving received data directly to a file. Der folgende Code ist für GetStream vorgesehenThe following code is for GetStream.

    public Stream GetStream(string data)
    {
        //this file path assumes the image is in
        // the Service folder and the service is executing
        // in service/bin 
        string filePath = Path.Combine(
            System.Environment.CurrentDirectory,
            ".\\..\\image.jpg");
        //open the file, this could throw an exception 
        //(e.g. if the file is not found)
        //having includeExceptionDetailInFaults="True" in config 
        // would cause this exception to be returned to the client
        try
        {
            FileStream imageFile = File.OpenRead(filePath);
            return imageFile;
        }
        catch (IOException ex)
        {
            Console.WriteLine(
                String.Format("An exception was thrown while trying to open file {0}", filePath));
            Console.WriteLine("Exception is: ");
            Console.WriteLine(ex.ToString());
            throw ex;
        }
    }
    
    Public Function GetStream(ByVal data As String) As Stream Implements IStreamingSample.GetStream
        'this file path assumes the image is in
        ' the Service folder and the service is executing
        ' in service/bin 
        Dim filePath = Path.Combine(System.Environment.CurrentDirectory, ".\..\image.jpg")
        'open the file, this could throw an exception 
        '(e.g. if the file is not found)
        'having includeExceptionDetailInFaults="True" in config 
        ' would cause this exception to be returned to the client
        Try
            Return File.OpenRead(filePath)
        Catch ex As IOException
            Console.WriteLine(String.Format("An exception was thrown while trying to open file {0}", filePath))
            Console.WriteLine("Exception is: ")
            Console.WriteLine(ex.ToString())
            Throw ex
        End Try
    End Function
    

Schreiben einer benutzerdefinierten StreamklasseWriting a custom stream

  1. Wenn jedes Element eines Datenstreams beim Senden oder Empfangen auf eine besondere Weise verarbeitet werden soll, müssen Sie eine benutzerdefinierte Streamklasse von der Stream-Klasse ableitenTo do special processing on each chunk of a data stream as it is being sent or received, derive a custom stream class from Stream. Der folgende Code enthält als Beispiel für einen benutzerdefinierten Stream die GetReversedStream-Methode und die ReverseStream-Klasse.As an example of a custom stream, the following code contains a GetReversedStream method and a ReverseStream class-.

    GetReversedStream erstellt eine neue Instanz der ReverseStream-Klasse und gibt eine Instanz dieser Klasse zurück.GetReversedStream creates and returns a new instance of ReverseStream. Die tatsächliche Verarbeitung erfolgt, wenn das System Daten aus dem ReverseStream-Objekt liest.The actual processing happens as the system reads from the ReverseStream object. Die ReverseStream.Read-Methode liest eine Gruppe von Bytes aus der zugrunde liegenden Datei, invertiert die Reihenfolge der Bytes und gibt die invertierten Bytes zurück.The ReverseStream.Read method reads a chunk of bytes from the underlying file, reverses them, then returns the reversed bytes. Diese Methode invertiert nicht den gesamten Dateiinhalt, sondern jeweils nur eine Gruppe von Bytes.This method does not reverse the entire file content; it reverses one chunk of bytes at a time. Dieses Beispiel zeigt, wie Daten im Streamingmodus verarbeitet werden, wenn Daten aus dem Stream gelesen oder in den Stream geschrieben werden.This example shows how you can perform stream processing as the content is being read to or written from the stream.

    class ReverseStream : Stream
    {
    
        FileStream inStream;
        internal ReverseStream(string filePath)
        {
            //opens the file and places a StreamReader around it
            inStream = File.OpenRead(filePath);
        }
        public override bool CanRead
        {
            get { return inStream.CanRead; }
        }
    
        public override bool CanSeek
        {
            get { return false; }
        }
    
        public override bool CanWrite
        {
            get { return false; }
        }
    
        public override void Flush()
        {
            throw new Exception("This stream does not support writing.");
        }
    
        public override long Length
        {
            get { throw new Exception("This stream does not support the Length property."); }
        }
    
        public override long Position
        {
            get
            {
                return inStream.Position;
            }
            set
            {
                throw new Exception("This stream does not support setting the Position property.");
            }
        }
    
        public override int Read(byte[] buffer, int offset, int count)
        {
            int countRead = inStream.Read(buffer, offset, count);
            ReverseBuffer(buffer, offset, countRead);
            return countRead;
        }
    
        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new Exception("This stream does not support seeking.");
        }
    
        public override void SetLength(long value)
        {
            throw new Exception("This stream does not support setting the Length.");
        }
    
        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new Exception("This stream does not support writing.");
        }
        public override void Close()
        {
            inStream.Close();
            base.Close();
        }
        protected override void Dispose(bool disposing)
        {
            inStream.Dispose();
            base.Dispose(disposing);
        }
        void ReverseBuffer(byte[] buffer, int offset, int count)
        {
    
            int i, j;
    
            for (i = offset, j = offset + count - 1; i < j; i++, j--)
            {
                byte currenti = buffer[i];
                buffer[i] = buffer[j];
                buffer[j] = currenti;
            }
    
        }
    }
    
    Friend Class ReverseStream
        Inherits Stream
    
        Private inStream As FileStream
    
        Friend Sub New(ByVal filePath As String)
            'opens the file and places a StreamReader around it
            inStream = File.OpenRead(filePath)
        End Sub
    
        Public Overrides ReadOnly Property CanRead() As Boolean
            Get
                Return inStream.CanRead
            End Get
        End Property
    
        Public Overrides ReadOnly Property CanSeek() As Boolean
            Get
                Return False
            End Get
        End Property
    
        Public Overrides ReadOnly Property CanWrite() As Boolean
            Get
                Return False
            End Get
        End Property
    
        Public Overrides Sub Flush()
            Throw New Exception("This stream does not support writing.")
        End Sub
    
        Public Overrides ReadOnly Property Length() As Long
            Get
                Throw New Exception("This stream does not support the Length property.")
            End Get
        End Property
    
        Public Overrides Property Position() As Long
            Get
                Return inStream.Position
            End Get
            Set(ByVal value As Long)
                Throw New Exception("This stream does not support setting the Position property.")
            End Set
        End Property
    
        Public Overrides Function Read(ByVal buffer() As Byte, _
                                       ByVal offset As Integer, _
                                       ByVal count As Integer) As Integer
    
            Dim countRead = inStream.Read(buffer, _
                                          offset, _
                                          count)
            ReverseBuffer(buffer, _
                          offset, _
                          countRead)
            Return countRead
        End Function
    
        Public Overrides Function Seek(ByVal offset As Long, _
                                       ByVal origin As SeekOrigin) As Long
            Throw New Exception("This stream does not support seeking.")
        End Function
    
        Public Overrides Sub SetLength(ByVal value As Long)
            Throw New Exception("This stream does not support setting the Length.")
        End Sub
    
        Public Overrides Sub Write(ByVal buffer() As Byte, _
                                   ByVal offset As Integer, _
                                   ByVal count As Integer)
            Throw New Exception("This stream does not support writing.")
        End Sub
    
        Public Overrides Sub Close()
            inStream.Close()
            MyBase.Close()
        End Sub
    
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            inStream.Dispose()
            MyBase.Dispose(disposing)
        End Sub
    
        Private Sub ReverseBuffer(ByVal buffer() As Byte, _
                                  ByVal offset As Integer, _
                                  ByVal count As Integer)
    
            Dim i = offset
            Dim j = offset + count - 1
    
            Do While i < j
                Dim currenti = buffer(i)
                buffer(i) = buffer(j)
                buffer(j) = currenti
                i += 1
                j -= 1
            Loop
    
        End Sub
    End Class
    

Siehe auchSee Also

Umfangreiche Daten und StreamingLarge Data and Streaming
StreamStream