Megosztás a következőn keresztül:


Útmutató: Streamelés engedélyezése

A Windows Communication Foundation (WCF) pufferelt vagy streamelt átvitelekkel küldhet üzeneteket. Az alapértelmezett pufferelt átviteli módban az üzenetet teljesen kézbesíteni kell, mielőtt a fogadó elolvashatja. Streamátviteli módban a fogadó megkezdheti az üzenet feldolgozását, mielőtt az teljesen kézbesíthető lenne. A streamelési mód akkor hasznos, ha az átadott információk hosszadalmasak és sorosan feldolgozhatók. A streamelési mód akkor is hasznos, ha az üzenet túl nagy ahhoz, hogy teljes mértékben pufferelje.

A streamelés engedélyezéséhez adja meg a OperationContract megfelelőt, és engedélyezze a streamelést az átviteli szinten.

Adatok streamelése

  1. Az adatok streameléséhez a OperationContract szolgáltatásnak két követelménynek kell megfelelnie:

    1. A továbbítandó adatokat tartalmazó paraméternek kell lennie a metódus egyetlen paraméterének. Ha például a bemeneti üzenet a továbbítandó üzenet, a műveletnek pontosan egy bemeneti paramétert kell tartalmaznia. Hasonlóképpen, ha a kimeneti üzenetet streamelni szeretné, a műveletnek pontosan egy kimeneti paraméterrel vagy egy visszatérési értékkel kell rendelkeznie.

    2. A paraméter és a visszatérési érték Streamlegalább egyik típusának vagy , Messagevagy IXmlSerializable.

    Az alábbi példa egy streamelt adatokra vonatkozó szerződésre mutat be példát.

    [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
    

    A GetStream művelet pufferelt bemeneti adatokat stringfogad, amelyeket pufferel, és a streamelt adatokat ad vissza Stream. Ezzel szemben UploadStream egy Stream (streamelt) és egy bool (pufferelt) értéket ad vissza. EchoStream veszi és adja vissza Stream , és egy példa egy olyan műveletre, amelynek bemeneti és kimeneti üzenetei egyaránt streamelve vannak. Végül nem vesz fel bemeneteket, GetReversedStream és egy (streamelt) értéket ad vissza Stream .

  2. A streamelést engedélyezni kell a kötésen. Beállíthat egy tulajdonságot TransferMode , amely az alábbi értékek egyikét veheti igénybe:

    1. Buffered,

    2. Streamed, amely mindkét irányban lehetővé teszi a streamelt kommunikációt.

    3. StreamedRequest, amely csak a kérés streamelését teszi lehetővé.

    4. StreamedResponse, amely csak a válasz streamelt átvitelét teszi lehetővé.

    A BasicHttpBinding tulajdonságot a TransferMode kötésen teszi elérhetővé, ahogyan az és NetNamedPipeBindinga NetTcpBinding . A TransferMode tulajdonság az átviteli kötési elemen is beállítható, és egyéni kötésben is használható.

    Az alábbi minták bemutatják, hogyan állítható be TransferMode kód és a konfigurációs fájl módosításával. A minták szintén 64 MB-ra állítják be a maxReceivedMessageSize tulajdonságot, így a maximálisan engedélyezett méretű üzenetek fogadhatók. Az alapértelmezett érték maxReceivedMessageSize 64 KB, ami általában túl alacsony a streamelési forgatókönyvekhez. Állítsa be ezt a kvótabeállítást az alkalmazás által várt üzenetek maximális méretétől függően. Azt is vegye figyelembe, hogy maxBufferSize a pufferelt maximális méretet szabályozza, és megfelelő módon állítja be.

    1. A minta alábbi konfigurációs kódrészlete azt mutatja be, hogy a TransferMode tulajdonság streamelésre van-e állítva a basicHttpBinding http-kötésen és egy egyéni HTTP-kötésen.

      <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. Az alábbi kódrészlet azt mutatja be, hogy a TransferMode tulajdonság streamelésre van-e állítva az basicHttpBinding egyéni HTTP-kötésen.

      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. Az alábbi kódrészlet bemutatja, hogy a TransferMode tulajdonság streamelésre van-e állítva egy egyéni TCP-kötésen.

      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. A műveletek GetStream, UploadStreamés EchoStream minden foglalkozik küld adatokat közvetlenül egy fájlból, vagy mentse a kapott adatokat közvetlenül egy fájlba. A következő kód a következő: 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
    

Egyéni stream írása

  1. Ha speciális feldolgozást szeretne végezni az adatfolyamok minden egyes adattömbjén az elküldés vagy fogadás során, származtatassunk egy egyéni streamosztályt a forrásból Stream. Az egyéni streamek példájaként az alábbi kód egy metódust és egy GetReversedStream osztályt ReverseStream tartalmaz.

    GetReversedStream új példányt ReverseStreamhoz létre és ad vissza. A tényleges feldolgozás akkor történik, amikor a rendszer beolvassa az ReverseStream objektumból. A ReverseStream.Read metódus a mögöttes fájlból beolvassa a bájtok egy részét, megfordítja őket, majd visszaadja a fordított bájtokat. Ez a módszer nem fordítja vissza a teljes fájltartalmat; egyszerre egy bájttömbnyit fordít vissza. Ez a példa bemutatja, hogyan végezhet streamfeldolgozást, amikor a tartalmat beolvassa vagy a streamből írja.

    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
    

Lásd még