Megosztás:


Áramlat

A Stream-minta bemutatja a streamelési módú kommunikáció használatát. A szolgáltatás számos olyan műveletet tesz elérhetővé, amelyek streameket küldenek és fogadnak. Ez a minta saját üzemeltetésű. Az ügyfél és a szolgáltatás egyaránt konzolprogramok.

Megjegyzés:

A minta telepítési eljárása és összeállítási utasításai a témakör végén találhatók.

A Windows Communication Foundation (WCF) két átviteli módban tud kommunikálni – pufferelt vagy streamelt üzemmódban. Az alapértelmezett pufferelt átviteli módban egy üzenetet teljes egészében kézbesíteni kell, mielőtt a fogadó felolvassa. Streamátviteli módban a fogadó megkezdheti az üzenet feldolgozását, mielőtt az teljes mértékben 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.

Streamelési és szolgáltatási szerződések

A streamelést érdemes megfontolni egy szolgáltatási szerződés tervezésekor. Ha egy művelet nagy mennyiségű adatot fogad vagy ad vissza, érdemes lehet ezeket az adatokat streamelni, hogy elkerülje a bemeneti vagy kimeneti üzenetek pufferelése miatti magas memóriakihasználtságot. Az adatok streameléséhez az adatokat tartalmazó paraméternek kell lennie az üzenet 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. Mindkét esetben a paraméter vagy a visszatérési érték típusa legyen Stream, Message vagy IXmlSerializable. Az alábbiakban a streamelési mintában használt szolgáltatási szerződést használjuk.

[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();

}

A GetStream művelet a bemeneti adatokat sztring formátumban fogadja, amelyet pufferelnek, és egy adatfolyamként visszaadott Stream értéket ad vissza. Ezzel szemben, UploadStream egy Stream (streamelt) adatfolyamot fogad be, és egy bool (pufferelt) adatfolyamot 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 GetReversedStream nem vesz fel bemeneteket, és visszaad egy Stream streamelt értéket.

Streamelt átvitelek engedélyezése

A korábban ismertetett műveleti szerződések meghatározása a programozási modell szintjén biztosítja a streamelést. Ha ott megáll, az átvitel továbbra is puffereli a teljes üzenettartalmat. Az adatfolyam átvitelének engedélyezéséhez válasszon egy átviteli módot az átviteli kötőelemnél. A kötési elemnek van egy TransferMode tulajdonsága, amely a következőre Bufferedállítható be: , Streamedvagy StreamedRequestStreamedResponse. Az átviteli mód beállítása, hogy Streamed mindkét irányban lehetővé teszi a streamelt kommunikációt. Az átviteli mód beállítása a StreamedRequest vagy StreamedResponse értékre azt eredményezi, hogy csak a kérésben, illetve a válaszban engedélyezett a streamelési kommunikáció.

A basicHttpBinding ugyanúgy közzéteszi a TransferMode tulajdonságot a kötésen, mint ahogyan NetTcpBinding és NetNamedPipeBinding. Más átvitelek esetén létre kell hoznia egy egyéni kötést az átviteli mód beállításához.

A minta alábbi konfigurációs kódja azt mutatja be, hogyan van a TransferMode tulajdonság streamelésre állítva az basicHttpBinding egyéni HTTP-kötésnél.

<!-- An example basicHttpBinding using streaming. -->
<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>

Az transferModeStreamed beállításán kívül az előző konfigurációs kód a maxReceivedMessageSize-t 64 MB-ra állítja. Védelmi mechanizmusként maxReceivedMessageSize a maximálisan engedélyezett méretű üzenetek fogadására vonatkozó korlátot helyez el. Az alapértelmezett érték maxReceivedMessageSize 64 KB, ami általában túl alacsony a streamelési forgatókönyvekhez.

Adatok feldolgozása streamelés közben

A műveletek GetStream, UploadStream és EchoStream mind a közvetlen adatküldéssel foglalkoznak fájlból, vagy a kapott adatok közvetlen mentésével fájlba. Bizonyos esetekben azonban szükség van nagy mennyiségű adat küldésére vagy fogadására, valamint az adatok adattömbjeinek feldolgozására az elküldés vagy fogadás során. Az ilyen forgatókönyvek megoldásának egyik módja egy saját stream írása (egy osztályból Stream származtatva), amely az adatokat olvasás vagy írás közben dolgozza fel. A GetReversedStream művelet és ReverseStream osztály egy példa erre.

GetReversedStream létrehoz és visszaad egy új ReverseStream példányt. A tényleges feldolgozás akkor történik, amikor a rendszer erről az objektumról ReverseStream olvas. Az ReverseStream.Read implementáció 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 nem fordítja vissza a teljes fájltartalmat; egyszerre egy bájttömbnyit fordít vissza. Ez a példa bemutatja, hogyan végezhet adatfolyam-feldolgozást a tartalom olvasása vagy írása során a streamből és a streambe.

class ReverseStream : Stream
{

    FileStream inStream;
    internal ReverseStream(string filePath)
    {
        //Opens the file and places a StreamReader around it.
        inStream = File.OpenRead(filePath);
    }

    // Other methods removed for brevity.

    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 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;
        }

    }
}

Minta tesztelése

A minta futtatásához először hozza létre a szolgáltatást és az ügyfelet is a dokumentum végén található utasításokat követve. Ezután indítsa el a szolgáltatást és az ügyfelet két különböző konzolablakban. Amikor a kliens elindul, megvárja, hogy az ENTER billentyűt lenyomja, amikor a szolgáltatás készen áll. Az ügyfél ezután meghívja a metódusokat GetStream(), UploadStream() majd GetReversedStream() először HTTP-en, majd TCP-en keresztül. Íme egy példakimenet a szolgáltatásból, amelyet az ügyfél példakimenete követ:

Szolgáltatás kimenete:

The streaming service is ready.
Press <ENTER> to terminate service.

Saving to file D:\...\uploadedfile
......................
File D:\...\uploadedfile saved
Saving to file D:\...\uploadedfile
...............
File D:\...\uploadedfile saved

Ügyfél kimenete:

Press <ENTER> when service is ready
------ Using HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream

File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
......................
Wrote 33405 bytes to stream

File D:\...\clientfile saved
------ Using Custom HTTP ------
Calling GetStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream

File D:\...\clientfile saved
Calling UploadStream()
Calling GetReversedStream()
Saving to file D:\...\clientfile
...............
Wrote 33405 bytes to stream

File D:\...\clientfile saved

Press <ENTER> to terminate client.

A példa beállítása, elkészítése és futtatása

  1. Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták One-Time beállítási eljárását.

  2. A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse Windows Communication Foundation-mintákcímű témakör utasításait.

  3. Ha a mintát egy vagy több gép közötti konfigurációban szeretné futtatni, kövesse A Windows Communication Foundation-minták futtatásacímű témakör utasításait.

Megjegyzés:

Ha a Svcutil.exe használatával hozza létre újra a minta konfigurációját, mindenképpen módosítsa az ügyfélkonfiguráció végpontnevét az ügyfélkódnak megfelelően.