Delen via


Procedure: Streaming inschakelen

Windows Communication Foundation (WCF) kan berichten verzenden met behulp van gebufferde of gestreamde overdrachten. In de standaardmodus voor gebufferde overdracht moet een bericht volledig worden bezorgd voordat een ontvanger het kan lezen. In de streamingoverdrachtmodus kan de ontvanger het bericht verwerken voordat het volledig wordt bezorgd. De streamingmodus is handig wanneer de informatie die wordt doorgegeven, lang is en serieel kan worden verwerkt. De streamingmodus is ook handig wanneer het bericht te groot is om volledig te worden gebufferd.

Als u streaming wilt inschakelen, definieert u de OperationContract juiste en schakelt u streaming in op transportniveau.

Gegevens streamen

  1. Als u gegevens wilt streamen, moet de OperationContract service aan twee vereisten voldoen:

    1. De parameter die de gegevens bevat die moeten worden gestreamd, moet de enige parameter in de methode zijn. Als het invoerbericht bijvoorbeeld het bericht is dat moet worden gestreamd, moet de bewerking precies één invoerparameter hebben. Als het uitvoerbericht moet worden gestreamd, moet de bewerking ook exact één uitvoerparameter of een retourwaarde hebben.

    2. Ten minste één van de typen van de parameter en retourwaarde moet Streamofwel , Messageof IXmlSerializable.

    Hier volgt een voorbeeld van een contract voor gestreamde gegevens.

    [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
    

    De GetStream bewerking ontvangt enkele gebufferde invoergegevens als een string, die wordt gebufferd en retourneert een Stream, die wordt gestreamd. Neemt daarentegen UploadStream een Stream (gestreamd) en retourneert een bool (gebufferd). EchoStream neemt en retourneert Stream en is een voorbeeld van een bewerking waarvan de invoer- en uitvoerberichten beide worden gestreamd. GetReversedStream Neemt ten slotte geen invoer en retourneert een Stream (gestreamde) invoer.

  2. Streaming moet zijn ingeschakeld voor de binding. U stelt een TransferMode eigenschap in, die een van de volgende waarden kan aannemen:

    1. Buffered,

    2. Streamed, waardoor streamingcommunicatie in beide richtingen mogelijk is.

    3. StreamedRequest, waarmee de aanvraag alleen kan worden gestreamd.

    4. StreamedResponse, waarmee het antwoord alleen kan worden gestreamd.

    De BasicHttpBinding eigenschap wordt TransferMode weergegeven op de binding, zoals wel NetTcpBinding en NetNamedPipeBinding. De TransferMode eigenschap kan ook worden ingesteld op het transportbindingselement en wordt gebruikt in een aangepaste binding.

    In de volgende voorbeelden ziet u hoe u kunt instellen TransferMode op code en door het configuratiebestand te wijzigen. De voorbeelden stellen de eigenschap ook in op 64 MB, waardoor een limiet wordt ingesteld maxReceivedMessageSize op de maximaal toegestane grootte van berichten die worden ontvangen. De standaardwaarde maxReceivedMessageSize is 64 kB, wat meestal te laag is voor streamingscenario's. Stel deze quotuminstelling in, afhankelijk van de maximale grootte van berichten die uw toepassing verwacht te ontvangen. Houd er ook rekening mee dat maxBufferSize u de maximale grootte bepaalt die wordt gebufferd en op de juiste manier wordt ingesteld.

    1. In het volgende configuratiefragment uit het voorbeeld ziet u hoe u de TransferMode eigenschap instelt op streaming op de basicHttpBinding en een aangepaste 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. Het volgende codefragment toont het instellen van de TransferMode eigenschap op streaming op de basicHttpBinding en een aangepaste 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. Het volgende codefragment toont het instellen van de TransferMode eigenschap op streaming op een aangepaste 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. De bewerkingen, UploadStreamen EchoStream alle bewerkingen GetStreamhebben betrekking op het rechtstreeks verzenden van gegevens uit een bestand of het rechtstreeks opslaan van ontvangen gegevens naar een bestand. De volgende code is bedoeld voor 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
    

Een aangepaste stream schrijven

  1. Als u speciale verwerking wilt uitvoeren op elk segment van een gegevensstroom terwijl deze wordt verzonden of ontvangen, moet u een aangepaste stroomklasse afleiden van Stream. Als voorbeeld van een aangepaste stream bevat de volgende code een GetReversedStream methode en een ReverseStream klasse.

    GetReversedStream maakt en retourneert een nieuw exemplaar van ReverseStream. De werkelijke verwerking vindt plaats wanneer het systeem uit het ReverseStream object leest. De ReverseStream.Read methode leest een segment van bytes uit het onderliggende bestand, keert deze om en retourneert vervolgens de omgekeerde bytes. Met deze methode wordt de volledige bestandsinhoud niet omgekeerd; hiermee wordt één segment van bytes tegelijk omgekeerd. In dit voorbeeld ziet u hoe u stroomverwerking kunt uitvoeren terwijl de inhoud wordt gelezen naar of geschreven vanuit de 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
    

Zie ook