Dela via


Gör så här: Aktivera direktuppspelning

Windows Communication Foundation (WCF) kan skicka meddelanden med buffrade eller strömmade överföringar. I standardläget för buffrad överföring måste ett meddelande levereras helt innan en mottagare kan läsa det. I läget för direktuppspelningsöverföring kan mottagaren börja bearbeta meddelandet innan det levereras helt. Strömningsläget är användbart när den information som skickas är lång och kan bearbetas seriellt. Strömningsläge är också användbart när meddelandet är för stort för att vara helt buffrat.

Om du vill aktivera direktuppspelning definierar du rätt OperationContract och aktiverar direktuppspelning på transportnivå.

Så här strömmar du data

  1. För att kunna strömma data OperationContract måste tjänsten uppfylla två krav:

    1. Parametern som innehåller data som ska strömmas måste vara den enda parametern i metoden. Om indatameddelandet till exempel är det som ska strömmas måste åtgärden ha exakt en indataparameter. Om utdatameddelandet ska strömmas måste åtgärden ha antingen exakt en utdataparameter eller ett returvärde.

    2. Minst en av parametertyperna och returvärdet måste vara antingen Stream, Messageeller IXmlSerializable.

    Följande är ett exempel på ett kontrakt för strömmade 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
    

    Åtgärden GetStream tar emot vissa buffrade indata som en string, som är buffrad och returnerar en Stream, som strömmas. Omvänt UploadStream tar in en Stream (strömmad) och returnerar en bool (buffrad). EchoStream tar och returnerar Stream och är ett exempel på en åtgärd vars indata- och utdatameddelanden båda strömmas. GetReversedStream Slutligen tar inga indata och returnerar en Stream (strömmad).

  2. Strömning måste vara aktiverat på bindningen. Du anger en TransferMode egenskap som kan innehålla något av följande värden:

    1. Buffered,

    2. Streamed, vilket möjliggör direktuppspelningskommunikation i båda riktningarna.

    3. StreamedRequest, vilket endast möjliggör direktuppspelning av begäran.

    4. StreamedResponse, som endast aktiverar direktuppspelning av svaret.

    Exponerar BasicHttpBindingTransferMode egenskapen för bindningen, precis som NetTcpBinding och NetNamedPipeBinding. Egenskapen TransferMode kan också anges för transportbindningselementet och användas i en anpassad bindning.

    Följande exempel visar hur du anger efter TransferMode kod och genom att ändra konfigurationsfilen. Exemplen anger maxReceivedMessageSize också egenskapen till 64 MB, vilket sätter ett tak för den maximala tillåtna storleken på meddelanden som tas emot. Standardvärdet maxReceivedMessageSize är 64 KB, vilket vanligtvis är för lågt för strömningsscenarier. Ange den här kvotinställningen beroende på den maximala storleken på meddelanden som programmet förväntar sig att ta emot. Observera också att maxBufferSize styr den maximala storleken som buffrats och ställer in den på rätt sätt.

    1. Följande konfigurationsfragment från exemplet visar hur du ställer in TransferMode egenskapen på direktuppspelning på basicHttpBinding och en anpassad HTTP-bindning.

      <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. Följande kodfragment visar hur du ställer in TransferMode egenskapen på direktuppspelning på basicHttpBinding och en anpassad HTTP-bindning.

      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. Följande kodfragment visar hur du ställer in TransferMode egenskapen på direktuppspelning på en anpassad TCP-bindning.

      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. Åtgärderna GetStream, UploadStreamoch EchoStream alla hanterar att skicka data direkt från en fil eller spara mottagna data direkt till en fil. Följande kod är för 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
    

Skriva en anpassad ström

  1. Om du vill utföra särskild bearbetning på varje segment i en dataström när den skickas eller tas emot härleder du en anpassad strömklass från Stream. Som ett exempel på en anpassad ström innehåller följande kod en GetReversedStream metod och en ReverseStream klass-.

    GetReversedStream skapar och returnerar en ny instans av ReverseStream. Den faktiska bearbetningen sker när systemet läser från objektet ReverseStream . Metoden ReverseStream.Read läser ett bytesegment från den underliggande filen, återställer dem och returnerar sedan omvända byte. Den här metoden återställer inte hela filinnehållet. den omvänt en bit byte i taget. Det här exemplet visar hur du kan utföra dataströmbearbetning när innehållet läse till eller skrivs från dataströmmen.

    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
    

Se även