Stream
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.
Feljegyzé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éternek vagy a visszatérési értéknek vagy Stream
a paraméternek Message
vagy IXmlSerializable
a visszatérési értéknek kell lennie. 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 sztringként fogad néhány bemeneti adatot, amely pufferelt, és egy Stream
streamelt értéket ad vissza. 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
.
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 átviteli stream engedélyezéséhez válasszon egy átviteli módot az átvitel kötési elemén. A kötési elemnek van egy TransferMode
tulajdonsága, amely a következőre Buffered
állítható be: , Streamed
vagy StreamedRequest
StreamedResponse
. 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 streamelési kommunikációra StreamedRequest
vagy StreamedResponse
csak a kérésben vagy a válaszban engedélyezett.
A basicHttpBinding
tulajdonság a TransferMode
kötésen ugyanúgy lesz közzétéve, mint NetTcpBinding
a 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, hogy a TransferMode
tulajdonság streamelésre van-e állítva az basicHttpBinding
egyéni HTTP-kötésen:
<!-- 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>
A beállítás mellett az transferMode
Streamed
előző konfigurációs kód 64 MB-ra állítja.maxReceivedMessageSize
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.
Adatfolyamként történő adatfeldolgozás
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. 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 egyéni stream írása (amely abból származik Stream), amely olvasás vagy írás során dolgozza fel az adatokat. Erre GetReversedStream
példa a művelet és ReverseStream
az osztály.
GetReversedStream
új példányt ReverseStream
hoz létre és ad vissza. 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 streamfeldolgozást a tartalom olvasása vagy írása közben a streambe é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;
}
}
}
A minta futtatása
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 az ügyfél elindul, megvárja, amíg 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 minta beállítása, összeállítása és futtatása
Győződjön meg arról, hogy elvégezte a Windows Communication Foundation-minták egyszeri beállítási eljárását.
A megoldás C# vagy Visual Basic .NET kiadásának létrehozásához kövesse a Windows Communication Foundation-minták készítéséhez szükséges utasításokat.
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ásával kapcsolatos utasításokat.
Feljegyzés
Ha Svcutil.exe használ a minta konfigurációjának újragenerálásához, mindenképpen módosítsa az ügyfélkonfiguráció végpontnevét az ügyfélkódnak megfelelően.