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


Nagyméretű adatok és streamelés

A Windows Communication Foundation (WCF) egy XML-alapú kommunikációs infrastruktúra. Mivel az XML-adatok általában az XML 1.0 specifikációban meghatározott szabványos szöveges formátumban vannak kódolva, a csatlakoztatott rendszerek fejlesztői és tervezői általában aggódnak a hálózaton keresztül küldött üzenetek vezetékes lábnyoma (vagy mérete) miatt, és az XML szövegalapú kódolása különleges kihívásokat jelent a bináris adatok hatékony átvitele szempontjából.

Alapvető szempontok

A WCF-hez kapcsolódó alábbi információk háttérinformációinak biztosításához ez a szakasz kiemeli a kódolásokkal, bináris adatokkal és streameléssel kapcsolatos általános aggályokat és szempontokat, amelyek általában a csatlakoztatott rendszerinfrastruktúrákra vonatkoznak.

Adatok kódolása: Szöveg és bináris

A gyakran kifejezett fejlesztői aggodalmak közé tartozik az a felfogás, hogy az XML-nek jelentős többlettere van a bináris formátumokhoz képest a kezdőcímkék és a zárócímkék ismétlődő jellege miatt, hogy a numerikus értékek kódolása jelentősen nagyobbnak tekinthető, mivel szöveges értékekben vannak kifejezve, és hogy a bináris adatok nem fejezhetők ki hatékonyan, mert kifejezetten szövegformátumba való beágyazáshoz kell őket kódolni.

Bár számos ilyen és hasonló aggály érvényes, az XML-webszolgáltatások környezetében lévő XML-szöveg kódolású üzenetek és a binárisan kódolt üzenetek között az örökölt távoli eljáráshívási (RPC) környezetekben gyakran sokkal kisebb a tényleges különbség, mint amit a kezdeti megfontolás javasolhat.

Bár az XML-szöveg kódolású üzenetek transzparensek és "emberi olvashatók", a bináris üzenetek gyakran meglehetősen homályosak, és nehezen dekódolhatók eszközök nélkül. Ez az olvashatóságbeli különbség azt eredményezi, hogy a bináris üzenetek gyakran beágyazott metaadatokat is hordoznak a hasznos adatokban, ami ugyanúgy többletterhelést jelent, mint az XML szöveges üzeneteknél. Ez különösen igaz a bináris formátumokra, amelyek laza csatolási és dinamikus meghívási képességeket kívánnak biztosítani.

A bináris formátumok azonban gyakran tartalmaznak ilyen leíró metaadat-információkat egy "fejlécben", amely az alábbi adatrekordok adatelrendezését is deklarálja. A hasznos adatok ezután ezt a gyakori metaadatblokk-deklarációt követik, minimális többletterhelés mellett. Ezzel szemben az XML az egyes adatelemeket egy elembe vagy attribútumba foglalja, így az egyes szerializált hasznos adatobjektumok ismétlődően tartalmazzák a beágyazó metaadatokat. Ennek eredményeképpen az egyetlen szerializált hasznos adatobjektum mérete hasonló, amikor a szöveget bináris ábrázolásokkal hasonlítja össze, mivel néhány leíró metaadatot mindkettőhöz ki kell fejezni, de a bináris formátum a megosztott metaadatok leírásának előnyeit élvezi minden további hasznos adatobjektum esetében, amely az alacsonyabb általános terhelés miatt kerül átadásra.

Bizonyos adattípusok, például számok esetében azonban hátrányt jelenthet a rögzített méretű, bináris numerikus reprezentációk használata, például egyszerű szöveg helyett 128 bites decimális típus használata, mivel az egyszerű szöveges ábrázolás több bájttal kisebb lehet. A szöveges adatok méretbeli előnyei is lehetnek a jellemzően rugalmasabb XML-szövegkódolási lehetőségeknek, míg egyes bináris formátumok alapértelmezés szerint 16 bites vagy akár 32 bites Unicode formátumot is tartalmazhatnak, ami nem vonatkozik a .NET bináris XML-formátumra.

Ennek eredményeképpen a szöveg vagy a bináris üzenet közötti döntés nem olyan egyszerű, mint feltételezni, hogy a bináris üzenetek mindig kisebbek, mint az XML-szöveges üzenetek.

Az XML-szöveges üzenetek egyértelmű előnye, hogy szabványokon alapulnak, és a lehető legszélesebb körű együttműködési lehetőségeket és platformtámogatást kínálják. További információkért lásd a témakör későbbi, Kódolások című szakaszát.

Bináris tartalom

Az egyik terület, ahol a bináris kódolások jobbak a szöveges kódolásnál az eredményként kapott üzenetméret szempontjából, nagy bináris adatelemek, például képek, videók, hangklipek vagy bármilyen más átlátszatlan bináris adat, amelyet a szolgáltatások és a fogyasztók között kell cserélni. Ha xml-szövegbe szeretné illeszteni ezeket az adattípusokat, az általános módszer az, hogy a Base64 kódolással kódolja őket.

A Base64 kódolású sztringben minden karakter az eredeti 8 bites adatok 6 bites részét jelöli, ami a Base64 esetében 4:3 kódolási többletterhelési arányt eredményez, nem számítva a konvenció által gyakran hozzáadott további formázási karaktereket (kocsivissza/sorcsatorna). Bár az XML és a bináris kódolás közötti különbségek jelentősége általában a forgatókönyvtől függ, az 500 MB-os hasznos adat átvitele esetén a méretnövekedés általában nem elfogadható.

Ennek a kódolási többletterhelésnek a elkerülése érdekében az üzenetátviteli optimalizálási mechanizmus (MTOM) szabvány lehetővé teszi az üzenetben található nagy adatelemek külsővé alakítását, és azokat bináris adatként, speciális kódolás nélkül hordozza. Az MTOM-ban az üzeneteket a Simple Mail Transfer Protocol (SMTP) e-mailjeihez hasonlóan, mellékletekkel vagy beágyazott tartalommal (képekkel és más beágyazott tartalommal) cserélik; Az MTOM-üzenetek többrészes/kapcsolódó MIME-szekvenciákként vannak csomagolva, a gyökérrész pedig a tényleges SOAP-üzenet.

Az MTOM SOAP-üzenetek a kódolatlan verzióról módosulnak, így a megfelelő MIME-részekre hivatkozó speciális elemcímkék átveszik a bináris adatokat tartalmazó üzenet eredeti elemeinek helyét. Ennek eredményeképpen a SOAP-üzenet bináris tartalomra hivatkozik a vele küldött MIME-részekre mutatva, de egyébként csak XML-szöveges adatokat hordoz. Mivel ez a modell szorosan igazodik a jól bevált SMTP-modellhez, széles körű eszköztámogatás áll rendelkezésre az MTOM-üzenetek kódolásához és dekódolásához számos platformon, ami rendkívül interoperábilis választássá teszi.

A Base64-hez hasonlóan az MTOM-nak is van némi többlettere a MIME formátumhoz, így az MTOM használatának előnyei csak akkor jelennek meg, ha egy bináris adatelem mérete meghaladja az 1 KB-ot. A többletterhelés miatt az MTOM-kódolású üzenetek nagyobbak lehetnek, mint azok az üzenetek, amelyek Base64-kódolást használnak a bináris adatokhoz, ha a bináris hasznos adatok a küszöbérték alatt maradnak. További információkért lásd a témakör későbbi, Kódolások című szakaszát.

Nagy adattartalom

A korábban említett 500 MB hasznos adat szintén nagy helyi kihívást jelent a szolgáltatás és az ügyfél számára. A WCF alapértelmezés szerint pufferelt módban dolgozza fel az üzeneteket. Ez azt jelenti, hogy az üzenet teljes tartalma jelen van a memóriában az üzenet elküldése előtt vagy fogadása után. Bár ez a legtöbb forgatókönyv esetében jó stratégia, és olyan üzenetkezelési funkciókhoz szükséges, mint a digitális aláírások és a megbízható kézbesítés, a nagyméretű üzenetek kimeríthetik a rendszer erőforrásait.

A nagy hasznos adatok kezelésére szolgáló stratégia a streamelés. Bár az üzeneteket, különösen az XML-ben kifejezett üzeneteket általában viszonylag kompakt adatcsomagnak tekintik, az üzenetek mérete több gigabájt lehet, és több adatcsomaghoz hasonlíthat egy folyamatos adatfolyamhoz. Ha az adatok átvitele streamelési módban történik a pufferelt mód helyett, a küldő az üzenet törzsének tartalmát stream formájában teszi elérhetővé a címzett számára, és az üzenetinfrastruktúra folyamatosan továbbítja az adatokat a feladótól a fogadónak, amint az elérhetővé válik.

Az ilyen nagy adattartalmak átvitelének leggyakoribb forgatókönyve a bináris adatobjektumok átvitele, amelyek:

  • Nem lehet könnyen üzenetütemezésre bontani.

  • Időben kell kézbesíteni.

  • Az átvitel indításakor nem érhetők el teljes egészében.

Az ilyen korlátozásokkal nem rendelkező adatok esetében általában jobb, ha egy munkamenet hatókörén belül több üzenetsort is elküldünk, mint egy nagyméretű üzenetet. További információkért tekintse meg a jelen témakör későbbi részében található "Streamadatok" című szakaszt.

Nagy mennyiségű adat küldésekor be kell állítania az maxAllowedContentLength IIS-beállítást (további információ: IIS-kérelmek korlátainak konfigurálása) és a maxReceivedMessageSize kötési beállítás (például System.ServiceModel.BasicHttpBinding.MaxReceivedMessageSize vagy MaxReceivedMessageSize). A maxAllowedContentLength tulajdonság alapértelmezés szerint 28,6 MB, a maxReceivedMessageSize tulajdonság alapértelmezés szerint 64 KB.

Kódolások

A kódolás olyan szabályokat határoz meg, amelyekkel a vezetéken jeleníthet meg üzeneteket. A kódoló implementálja az ilyen kódolást, és a küldő oldalán felelős azért, hogy a memóriában Message egy bájtfolyam vagy bájtpuffer legyen, amely a hálózaton keresztül küldhető. A fogadó oldalon a kódoló bájtok sorozatát memóriabeli üzenetté alakítja.

A WCF három kódolót tartalmaz, és lehetővé teszi a saját kódolók írását és csatlakoztatását, ha szükséges.

A standard kötések mindegyike tartalmaz egy előre konfigurált kódolót, amely szerint a Net* előtaggal rendelkező kötések a bináris kódolót használják (az BinaryMessageEncodingBindingElement osztályt is beleértve), míg az WSHttpBindingBasicHttpBinding osztályok alapértelmezés szerint a szöveges üzenetkódolót használják (az TextMessageEncodingBindingElement osztály használatával).

Kódoló kötési eleme Leírás
TextMessageEncodingBindingElement A szöveges üzenet kódolója az összes HTTP-alapú kötés alapértelmezett kódolója, és a megfelelő választás minden olyan egyéni kötéshez, ahol az együttműködés a legnagyobb probléma. Ez a kódoló szabványos SOAP 1.1/SOAP 1.2 szöveges üzeneteket olvas és ír, a bináris adatok speciális kezelése nélkül. Ha egy System.ServiceModel.Channels.MessageVersion üzenet tulajdonsága a következőre MessageVersion.Nonevan állítva, a SOAP borítékburkoló ki lesz hagyva a kimenetből, és csak az üzenet törzsének tartalma lesz szerializálva.
MtomMessageEncodingBindingElement Az MTOM üzenetkódoló egy olyan szövegkódoló, amely speciális bináris adatok kezelését valósítja meg, és alapértelmezés szerint egyik szabványos kötésben sem használja, mert szigorúan eseti optimalizálási segédprogram. Ha az üzenet olyan bináris adatokat tartalmaz, amelyek túllépik azt a küszöbértéket, ahol az MTOM-kódolás előnyt jelent, az adatok az üzenetborítékot követő MIME-részre lesznek kiosztva. Lásd az MTOM engedélyezését a szakasz későbbi részében.
BinaryMessageEncodingBindingElement A bináris üzenetkódoló a Net* kötések alapértelmezett kódolója, és megfelelő választás, ha mindkét kommunikáló fél WCF-en alapul. A bináris üzenetkódoló a .NET bináris XML-formátumot használja, amely egy Microsoft-specifikus bináris reprezentáció AZ XML-információkészletekhez (Infosets), amely általában kisebb erőforrásigényt eredményez, mint az egyenértékű XML 1.0-ábrázolás, és bájtfolyamként kódolja a bináris adatokat.

A szöveges üzenetek kódolása általában a legjobb választás minden olyan kommunikációs útvonalhoz, amely együttműködést igényel, míg a bináris üzenetkódolás a legjobb választás bármely más kommunikációs útvonalhoz. A bináris üzenetkódolás általában kisebb üzenetméreteket eredményez egy üzenet szövegéhez képest, és fokozatosan még kisebb üzenetméretet is eredményez egy kommunikációs munkamenet időtartama alatt. A szövegkódolástól eltérően a bináris kódolásnak nem kell speciális kezelést használnia a bináris adatokhoz, például a Base64-et, hanem bájtként jelöli a bájtokat.

Ha a megoldás nem igényel együttműködési képességet, de továbbra is HTTP-átvitelt szeretne használni, létrehozhat egy egyéni kötést, BinaryMessageEncodingBindingElement amely az HttpTransportBindingElement osztályt használja az átvitelhez. Ha a szolgáltatásban több ügyfél is megköveteli az interoperabilitást, javasoljuk, hogy olyan párhuzamos végpontokat tegyen elérhetővé, amelyek mindegyike rendelkezik a megfelelő átviteli és kódolási lehetőségekkel a megfelelő ügyfelek számára.

MTOM engedélyezése

Ha az együttműködés követelmény, és nagy bináris adatokat kell küldeni, akkor az MTOM üzenetkódolás az alternatív kódolási stratégia, amelyet a standard BasicHttpBinding vagy WSHttpBinding kötéseken engedélyezhet a megfelelő MessageEncoding tulajdonság Mtom beállításával vagy írásávalMtomMessageEncodingBindingElement.CustomBinding Az MTOM-kódolási mintából kinyert alábbi példakód bemutatja, hogyan engedélyezheti az MTOM-t a konfigurációban.

<system.serviceModel>  
     …  
    <bindings>  
      <wsHttpBinding>  
        <binding name="ExampleBinding" messageEncoding="Mtom"/>  
      </wsHttpBinding>  
    </bindings>  
     …  
</system.serviceModel>  

Ahogy korábban említettük, az MTOM-kódolás használata a küldendő adatmennyiségtől függ. Mivel az MTOM a kötés szintjén engedélyezve van, az MTOM engedélyezése hatással van az adott végponton végzett összes műveletre.

Mivel az MTOM-kódoló mindig MTOM-kódolású MIME/többrészes üzenetet bocsát ki, függetlenül attól, hogy a bináris adatok külsőleg lesznek-e külsővé téve, általában csak olyan végpontokhoz kell engedélyeznie az MTOM-t, amelyek több mint 1 KB bináris adattal cserélnek üzeneteket. Emellett az MTOM-kompatibilis végpontokkal való használatra tervezett szolgáltatási szerződéseket lehetőség szerint korlátozni kell az ilyen adatátviteli műveletek megadására. A kapcsolódó vezérlőfunkcióknak külön szerződésben kell elhelyezkedniük. Ez a "csak MTOM" szabály csak az MTOM-kompatibilis végponton keresztül küldött üzenetekre vonatkozik; az MTOM-kódoló képes a bejövő nem MTOM-üzenetek dekódolása és elemzése is.

Az MTOM kódoló használata megfelel az összes többi WCF-funkciónak. Vegye figyelembe, hogy előfordulhat, hogy ez a szabály nem minden esetben figyelhető meg, például amikor munkamenet-támogatás szükséges.

Programozási modell

Függetlenül attól, hogy az alkalmazásban használt három beépített kódoló közül melyiket használja, a programozási élmény megegyezik a bináris adatok átvitelével. A különbség abban van, hogy a WCF hogyan kezeli az adatokat az adattípusok alapján.

[DataContract]  
class MyData  
{  
    [DataMember]  
    byte[] binaryBuffer;  
    [DataMember]  
    string someStringData;  
}

MTOM használata esetén az előző adatszerződés szerializálva lesz az alábbi szabályok szerint:

  • Ha binaryBuffer nincs null és nem tartalmaz külön-külön elegendő adatot az MTOM-externálási többletterhelés (MIME-fejlécek stb.) igazolásához a Base64 kódoláshoz képest, az adatok külsővé lesznek adva, és bináris MIME-részként hordozzák az üzenetet. Ha a küszöbértéket nem lépi túl, az adatok Base64-ként lesznek kódolva.

  • A sztring (és minden más, nem bináris típus) mindig sztringként jelenik meg az üzenettörzsben, mérettől függetlenül.

Az MTOM kódolásra gyakorolt hatás ugyanaz, ha explicit adatszerződést használ, ahogyan az előző példában látható, használjon paraméterlistát egy műveletben, beágyazott adatszerződéseket használjon, vagy egy adatszerződés-objektumot továbbít egy gyűjteményen belül. A bájttömbök mindig optimalizálásra jelöltek, és optimalizálva vannak, ha az optimalizálási küszöbértékek teljesülnek.

Feljegyzés

Az adatszerződések nem használhatnak System.IO.Stream származtatott típusokat. A streamelési adatokat a streamelési modell használatával kell kommunikálni, amely a következő "Streamelési adatok" szakaszban található.

Streamelési adatok

Ha nagy mennyiségű adatot kell továbbítania, a WCF streamátviteli módja megvalósítható alternatíva a memóriában lévő üzenetek pufferelésének és feldolgozásának alapértelmezett viselkedése helyett.

Ahogy korábban említettük, a streamelést csak nagy (szöveges vagy bináris tartalommal rendelkező) üzenetek esetén engedélyezze, ha az adatok nem szegmentáltak, ha az üzenetet időben kell kézbesíteni, vagy ha az adatok még nem állnak rendelkezésre teljes mértékben az átvitel indításakor.

Korlátozások

A streamelés engedélyezésekor nem használhat jelentős számú WCF-funkciót:

  • Az üzenet törzséhez tartozó digitális aláírások nem hajthatóak végre, mert kivonatot igényelnek az üzenet teljes tartalmán. Streamelés esetén a tartalom nem érhető el teljes mértékben az üzenetfejlécek létrehozásakor és elküldésekor, ezért digitális aláírás nem számítható ki.

  • A titkosítás a digitális aláírásoktól függ annak ellenőrzéséhez, hogy az adatok megfelelően lettek-e rekonstruálva.

  • A megbízható munkameneteknek pufferelniük kell az ügyfélen küldött üzeneteket az újrarendezéshez, ha egy üzenet elveszik az átvitel során, és az üzeneteket a szolgáltatáson kell tárolniuk, mielőtt átadják őket a szolgáltatás implementációjának, hogy megőrizzék az üzenetsorrendet abban az esetben, ha az üzenetek sorrenden kívül érkeznek.

Ezen funkcionális korlátozások miatt csak átviteli szintű biztonsági beállításokat használhat a streameléshez, és nem kapcsolhatja be a megbízható munkameneteket. A streamelés csak a következő rendszer által meghatározott kötésekkel érhető el:

Mivel a http-sel ellentétben a mögöttes átvitelek NetTcpBinding és NetNamedPipeBinding azok eredendően megbízható kézbesítési és kapcsolatalapú munkamenet-támogatással rendelkeznek, a gyakorlatban ez a két kötés csak minimálisan érinti ezeket a korlátozásokat.

A streamelés nem érhető el a Message Queuing (MSMQ) átvitelsel, ezért nem használható az osztálysal vagy MsmqIntegrationBinding az NetMsmqBinding osztálysal. A Message Queuing-átvitel csak korlátozott üzenetméretű pufferelt adatátvitelt támogat, míg az összes többi átvitel esetében nincs gyakorlati üzenetméretkorlát a forgatókönyvek túlnyomó többségére vonatkozóan.

A streamelés a társcsatorna-átvitel használatakor sem érhető el, ezért nem érhető el a NetPeerTcpBinding.

Streamelés és munkamenetek

Váratlan viselkedést kaphat, ha munkamenet-alapú kötéssel streameli a hívásokat. Az összes streamelési hívás egyetlen csatornán (a datagram csatornán) keresztül történik, amely akkor sem támogatja a munkameneteket, ha a használt kötés munkamenetek használatára van konfigurálva. Ha több ügyfél streameli a hívásokat ugyanarra a szolgáltatásobjektumra egy munkamenet-alapú kötésen keresztül, és a szolgáltatásobjektum egyidejűségi üzemmódja egyetlen, a példánykörnyezeti mód pedig PerSession értékre van állítva, minden hívásnak át kell mennie a datagram csatornán, így egyszerre csak egy hívás lesz feldolgozva. Egy vagy több ügyfél időtúllépést okozhat. A probléma megkerüléséhez állítsa a szolgáltatásobjektum példánykörnyezeti módját PerCall értékre, vagy az egyidejűséget többre.

Feljegyzés

A MaxConcurrentSessions nincs hatással ebben az esetben, mert csak egy "munkamenet" érhető el.

Streamelés engedélyezése

A streamelést a következő módokon engedélyezheti:

  • Kérések küldése és elfogadása streamelési módban, valamint válaszok elfogadása és visszaadása pufferelt módban (StreamedRequest).

  • Kérések küldése és elfogadása pufferelt módban, valamint válaszok elfogadása és visszaadása streamelt módban (StreamedResponse).

  • Kérések és válaszok küldése és fogadása streamelt módban mindkét irányban. (Streamed).

A streamelés letiltásához állítsa az átviteli módot Bufferedaz alapértelmezett beállításra az összes kötésen. Az alábbi kód bemutatja, hogyan állíthatja be az átviteli módot a konfigurációban.

<system.serviceModel>  
     …  
    <bindings>  
      <basicHttpBinding>  
        <binding name="ExampleBinding" transferMode="Streamed"/>  
      </basicHttpBinding>  
    </bindings>  
     …  
</system.serviceModel>  

Amikor a kötést kódban hozza létre, a kötés megfelelő TransferMode tulajdonságát (vagy egyéni kötés írása esetén az átviteli kötési elemet) a korábban említett értékek egyikére kell állítania.

A streamelést a kérések és válaszok, illetve mindkét irány esetében egymástól függetlenül, a kommunikáló felek mindkét oldalán bekapcsolhatja anélkül, hogy ez hatással van a működésre. Azonban mindig azt kell feltételezni, hogy az átvitt adatméret olyan jelentős, hogy a streamelés engedélyezése a kommunikációs kapcsolat mindkét végpontján indokolt. Platformfüggetlen kommunikáció esetén, ha az egyik végpont nincs implementálva a WCF-ben, a streamelés használatának lehetősége a platform streamelési képességeitől függ. Egy másik ritka kivétel lehet egy memóriahasználat-vezérelt forgatókönyv, amelyben egy ügyfélnek vagy szolgáltatásnak minimálisra kell csökkentenie a munkakészletét, és csak kis pufferméreteket engedhet meg magának.

Aszinkron streamelés engedélyezése

Az aszinkron streamelés engedélyezéséhez adja hozzá a DispatcherSynchronizationBehavior végpont viselkedését a szolgáltatás gazdagépéhez, és állítsa a tulajdonságát AsynchronousSendEnabled a következőre true: . Emellett hozzáadtuk a valódi aszinkron streamelés képességét is a küldési oldalon. Ez javítja a szolgáltatás méretezhetőségét olyan helyzetekben, amikor több ügyfélnek küld üzeneteket, amelyek némelyike esetleg hálózati torlódás miatt lassú, vagy egyáltalán nem olvas. Ezekben a forgatókönyvekben most nem tiltjuk le az egyes szálakat a szolgáltatáson ügyfélenként. Ez biztosítja, hogy a szolgáltatás sokkal több ügyfelet tudjon feldolgozni, ezáltal javítva a szolgáltatás méretezhetőségét.

Streamelt átvitelek programozási modellje

A streamelés programozási modellje egyszerű. Streamelt adatok fogadásához adjon meg egy műveleti szerződést, amely egyetlen Stream beírt bemeneti paraméterrel rendelkezik. Streamelt adatok visszaadása esetén adjon vissza egy Stream hivatkozást.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public interface IStreamedService  
{  
    [OperationContract]  
    Stream Echo(Stream data);  
    [OperationContract]  
    Stream RequestInfo(string query);  
    [OperationContract(OneWay=true)]  
    void ProvideInfo(Stream data);  
}  

Az előző példában szereplő művelet Echo egy streamet fogad és ad vissza, ezért egy kötésen kell használni a következővel Streamed: . A művelethez RequestInfoStreamedResponse a legmegfelelőbb, mert csak egy Stream. Az egyirányú művelet a legmegfelelőbb.StreamedRequest

Vegye figyelembe, hogy ha hozzáad egy második paramétert az alábbiakhoz Echo vagy ProvideInfo műveletekhez, a szolgáltatásmodell visszaáll egy pufferelt stratégiára, és a stream futásidejű szerializálási ábrázolását használja. Csak az egyetlen bemeneti streamparaméterrel rendelkező műveletek kompatibilisek a kérések végpontok közötti streameléssel.

Ez a szabály hasonlóan vonatkozik az üzenetszerződésekre. Ahogy az alábbi üzenetszerződésben látható, az üzenetszerződésben csak egyetlen törzstag lehet, amely stream. Ha további információkat szeretne kommunikálni a streamel, akkor ezeket az információkat az üzenetfejlécekben kell továbbítani. Az üzenet törzse kizárólag a streamtartalmak számára van fenntartva.

[MessageContract]  
public class UploadStreamMessage  
{  
   [MessageHeader]  
   public string appRef;  
   [MessageBodyMember]  
   public Stream data;  
}

A streamelt átvitelek befejeződnek, és az üzenet bezárul, amikor a stream eléri a fájl végét (EOF). Üzenet küldésekor (érték visszaadása vagy művelet meghívása) átadhat egy FileStream üzenetet, és a WCF-infrastruktúra ezt követően lekéri az összes adatot az adott streamből, amíg a streamet teljesen be nem olvasták és el nem érték az EOF-t. Ha olyan streamelt adatokat szeretne továbbítani a forráshoz, amely nem létezik ilyen előre összeállított Stream származtatott osztály, hozzon létre egy ilyen osztályt, fedje át az osztályt a streamforráson, és használja ezt argumentumként vagy visszatérési értékként.

Üzenet fogadásakor a WCF létrehoz egy streamet a Base64 kódolású üzenet törzsén (vagy az MTOM használata esetén a megfelelő MIME-részen), és a stream a tartalom elolvasásakor eléri az EOF-ot.

Az átviteli szintű streamelés bármilyen más üzenetszerződés-típussal (paraméterlistákkal, adatszerződés argumentumokkal és explicit üzenetszerződéssel) is működik, de mivel az ilyen típusú üzenetek szerializálása és deszerializálása a szerializáló általi pufferelést igényli, az ilyen szerződéses változatok használata nem ajánlott.

Különleges biztonsági szempontok a nagy méretű adatokhoz

Minden kötés lehetővé teszi a bejövő üzenetek méretének korlátozását a szolgáltatásmegtagadási támadások megelőzése érdekében. A BasicHttpBindingrendszer például egy System.ServiceModel.BasicHttpBinding.MaxReceivedMessageSize tulajdonságot tesz elérhetővé, amely a bejövő üzenet méretét határolja, és így az üzenet feldolgozásakor elérhető maximális memóriamennyiséget is megköti. Ez az egység bájtokban van beállítva, alapértelmezett értéke 65 536 bájt.

A nagy adatstreamelési forgatókönyvre jellemző biztonsági fenyegetés szolgáltatásmegtagadást idéz elő azáltal, hogy az adatokat puffereli, amikor a fogadó a streamelést várja. A WCF például mindig puffereli egy üzenet SOAP-fejléceit, így a támadók olyan nagy kártékony üzenetet hozhatnak létre, amely teljes egészében fejlécekből áll, hogy kényszerítse az adatok pufferelésére. Ha engedélyezve van a streamelés, a MaxReceivedMessageSize rendszer rendkívül nagy értékre állíthatja be, mivel a fogadó soha nem várja el, hogy a teljes üzenet egyszerre pufferelve legyen a memóriában. Ha a WCF-nek pufferelnie kell az üzenetet, a memória túlcsordul.

Ezért ebben az esetben nem elegendő a bejövő üzenetek maximális méretének korlátozása. A MaxBufferSize tulajdonság szükséges a WCF pufferelt memória korlátozásához. Fontos, hogy ezt biztonságos értékre állítsa (vagy tartsa meg az alapértelmezett értéken) a streamelés során. Tegyük fel például, hogy a szolgáltatásnak legfeljebb 4 GB méretű fájlokat kell fogadnia, és a helyi lemezen kell tárolnia őket. Tegyük fel azt is, hogy a memória úgy van korlátozva, hogy egyszerre csak 64 KB adat pufferelhető. Ezután 4 GB-ra és MaxBufferSize 64 KB-ra állíthatja MaxReceivedMessageSize be. Emellett a szolgáltatás implementációjában gondoskodnia kell arról, hogy csak a bejövő streamből olvasson 64 KB-os adattömbökben, és ne olvassa be a következő adattömbet, mielőtt az előző lemezre lett írva, és elvetette a memóriából.

Azt is fontos megérteni, hogy ez a kvóta csak a WCF által végzett pufferelést korlátozza, és nem tud védelmet nyújtani a saját szolgáltatásában vagy ügyfélalkalmazásában végzett pufferelés ellen. A további biztonsági szempontokról további információt az adatok biztonsági szempontjai című témakörben talál.

Feljegyzés

A pufferelt vagy streamelt átvitelek használatára vonatkozó döntés a végpont helyi döntése. HTTP-átvitelek esetén az átviteli mód nem propagálja a kapcsolatot, sem a proxykiszolgálókat és más közvetítőket. Az átviteli mód beállítása nem jelenik meg a szolgáltatási felület leírásában. Miután létrehoz egy WCF-ügyfelet egy szolgáltatásnak, a mód beállításához szerkesztenie kell a streamelt átvitelekkel használni kívánt szolgáltatások konfigurációs fájlját. TCP- és elnevezett csőátvitelek esetén az átviteli mód házirend-állításként propagálódik.

Lásd még