Delen via


Grote gegevens en streaming

Windows Communication Foundation (WCF) is een op XML gebaseerde communicatie-infrastructuur. Omdat XML-gegevens vaak worden gecodeerd in de standaardtekstindeling die is gedefinieerd in de XML 1.0-specificatie, maken ontwikkelaars en architecten van verbonden systemen zich doorgaans zorgen over de draadvoetafdruk (of grootte) van berichten die via het netwerk worden verzonden, en de op tekst gebaseerde codering van XML vormt speciale uitdagingen voor de efficiënte overdracht van binaire gegevens.

Basisoverwegingen

Om achtergrondinformatie over de volgende informatie voor WCF te geven, worden in deze sectie enkele algemene aandachtspunten en overwegingen voor coderingen, binaire gegevens en streaming beschreven die doorgaans van toepassing zijn op verbonden systemeninfrastructuren.

Coderingsgegevens: tekst versus binair

Vaak uitgedrukte problemen van ontwikkelaars zijn de perceptie dat XML aanzienlijke overhead heeft in vergelijking met binaire indelingen vanwege de terugkerende aard van begintags en eindtags, dat de codering van numerieke waarden als aanzienlijk groter wordt beschouwd omdat ze worden uitgedrukt in tekstwaarden en dat binaire gegevens niet efficiënt kunnen worden uitgedrukt omdat deze speciaal moeten worden gecodeerd voor insluiten in een tekstindeling.

Hoewel veel van deze en vergelijkbare problemen geldig zijn, is het werkelijke verschil tussen gecodeerde XML-tekstberichten in een XML-webserviceomgeving en binaire gecodeerde berichten in een verouderde RPC-omgeving (Remote Procedure Call) vaak veel minder belangrijk dan de eerste overweging zou kunnen voorstellen.

Hoewel gecodeerde XML-tekstberichten transparant en 'menselijk leesbaar' zijn, zijn binaire berichten vaak redelijk verborgen in vergelijking en moeilijk te decoderen zonder hulpprogramma's. Dit verschil in leesbaarheid leidt ertoe dat binaire berichten ook vaak inlinemetagegevens bevatten in de nettolading, waardoor overhead wordt toegevoegd, net als bij XML-tekstberichten. Dit geldt met name voor binaire indelingen die zijn gericht op het bieden van losse koppelings- en dynamische aanroepmogelijkheden.

Binaire indelingen bevatten echter vaak dergelijke beschrijvende metagegevensinformatie in een 'header', die ook de gegevensindeling declareert voor de volgende gegevensrecords. De nettolading volgt vervolgens deze algemene declaratie van metagegevensblokken met minimale extra overhead. Xml plaatst daarentegen elk gegevensitem in een element of kenmerk, zodat de omsluitmetagegevens herhaaldelijk worden opgenomen voor elk geserialiseerd nettoladingobject. Als gevolg hiervan is de grootte van één geserialiseerd nettoladingsobject vergelijkbaar bij het vergelijken van tekst met binaire weergaven, omdat sommige beschrijvende metagegevens voor beide moeten worden uitgedrukt, maar de binaire indeling profiteert van de beschrijving van gedeelde metagegevens met elk extra nettoladingobject dat wordt overgedragen vanwege de lagere totale overhead.

Voor bepaalde gegevenstypen, zoals getallen, kan het echter een nadeel zijn van het gebruik van vaste grootte, binaire numerieke weergaven, zoals een 128-bits decimaal type in plaats van tekst zonder opmaak, omdat de weergave van tekst zonder opmaak mogelijk meerdere bytes kleiner is. Tekstgegevens hebben mogelijk ook grote voordelen van de doorgaans flexibelere XML-tekstcoderingsopties, terwijl sommige binaire indelingen standaard 16-bits of zelfs 32-bits Unicode zijn, die niet van toepassing is op de binaire XML-indeling van .NET.

Als gevolg hiervan is het kiezen tussen tekst of binair niet zo eenvoudig als ervan uitgaande dat binaire berichten altijd kleiner zijn dan XML-tekstberichten.

Een duidelijk voordeel van XML-tekstberichten is dat ze op standaarden zijn gebaseerd en de breedste keuze bieden aan interoperabiliteitsopties en platformondersteuning. Zie de sectie Coderingen verderop in dit onderwerp voor meer informatie.

Binaire inhoud

Een gebied waar binaire coderingen beter zijn dan tekstgebaseerde coderingen in termen van de resulterende berichtgrootte zijn grote binaire gegevensitems zoals afbeeldingen, video's, geluidsclips of een andere vorm van ondoorzichtige, binaire gegevens die moeten worden uitgewisseld tussen services en hun consumenten. Als u deze typen gegevens in XML-tekst wilt aanpassen, is het gebruikelijk om ze te coderen met behulp van de Base64-codering.

In een met Base64 gecodeerde tekenreeks vertegenwoordigt elk teken 6 bits van de oorspronkelijke 8-bits gegevens, wat resulteert in een 4:3-coderings-overheadverhouding voor Base64, waarbij geen extra opmaaktekens worden geteld (regelterugloop/regelfeed) die vaak volgens conventie worden toegevoegd. Hoewel de significantie van de verschillen tussen XML- en binaire coderingen doorgaans afhankelijk is van het scenario, is een groottewinst van meer dan 33% bij het verzenden van een nettolading van 500 MB meestal niet acceptabel.

Om deze coderingsoverhead te voorkomen, maakt het MTOM-standaard (Message Transmission Optimization Mechanism) het mogelijk om grote gegevenselementen die zijn opgenomen in een bericht te externaliseren en deze met het bericht als binaire gegevens te vervoeren zonder speciale codering. Met MTOM worden berichten op dezelfde manier uitgewisseld als SMTP-e-mailberichten (Simple Mail Transfer Protocol) met bijlagen of ingesloten inhoud (afbeeldingen en andere ingesloten inhoud); MTOM-berichten worden verpakt als mime-reeksen met meerdere onderdelen, waarbij het hoofdonderdeel het werkelijke SOAP-bericht is.

Een MTOM SOAP-bericht wordt gewijzigd van de niet-gecodeerde versie, zodat speciale elementtags die verwijzen naar de respectieve MIME-onderdelen, de plaats innemen van de oorspronkelijke elementen in het bericht met binaire gegevens. Als gevolg hiervan verwijst het SOAP-bericht naar binaire inhoud door te verwijzen naar de MIME-onderdelen die ermee worden verzonden, maar anders alleen XML-tekstgegevens bevat. Omdat dit model nauw is afgestemd op het gevestigde SMTP-model, is er brede ondersteuning voor het coderen en decoderen van MTOM-berichten op veel platforms, waardoor het een uiterst interoperabele keuze is.

Net als bij Base64 wordt MTOM ook geleverd met enige overhead voor de MIME-indeling, zodat voordelen van het gebruik van MTOM alleen worden gezien wanneer de grootte van een binair gegevenselement ongeveer 1 kB overschrijdt. Vanwege de overhead kunnen MTOM-gecodeerde berichten groter zijn dan berichten die gebruikmaken van Base64-codering voor binaire gegevens, als de binaire nettolading onder die drempelwaarde blijft. Zie de sectie Coderingen verderop in dit onderwerp voor meer informatie.

Grote gegevensinhoud

De eerder genoemde nettolading van 500 MB vormt ook een grote lokale uitdaging voor de service en de client. WCF verwerkt standaard berichten in de buffermodus. Dit betekent dat de volledige inhoud van een bericht aanwezig is in het geheugen voordat het wordt verzonden of nadat het is ontvangen. Hoewel dat een goede strategie is voor de meeste scenario's en nodig is voor berichtenfuncties zoals digitale handtekeningen en betrouwbare bezorging, kunnen grote berichten de resources van een systeem uitputten.

De strategie voor het verwerken van grote nettoladingen is streaming. Hoewel berichten, met name die uitgedrukt in XML, vaak worden beschouwd als relatief compacte gegevenspakketten, kan een bericht meerdere gigabytes groot zijn en lijken op een continue gegevensstroom meer dan een gegevenspakket. Wanneer gegevens worden overgebracht in de streamingmodus in plaats van in de buffermodus, maakt de afzender de inhoud van de berichttekst beschikbaar voor de ontvanger in de vorm van een stroom en stuurt de berichtinfrastructuur de gegevens continu door naar de ontvanger wanneer deze beschikbaar is.

Het meest voorkomende scenario waarin dergelijke grote gegevensinhoudsoverdrachten plaatsvinden, zijn overdrachten van binaire gegevensobjecten die:

  • Kan niet eenvoudig worden opgesplitst in een berichtenreeks.

  • Moet tijdig worden geleverd.

  • Zijn niet volledig beschikbaar wanneer de overdracht wordt gestart.

Voor gegevens die niet over deze beperkingen beschikken, is het meestal beter om reeksen berichten binnen het bereik van een sessie dan één groot bericht te verzenden. Zie de sectie Streaminggegevens verderop in dit onderwerp voor meer informatie.

Wanneer u grote hoeveelheden gegevens verzendt, moet u de maxAllowedContentLength IIS-instelling instellen (zie IIS-aanvraaglimieten configureren) en de maxReceivedMessageSize bindingsinstelling (bijvoorbeeld System.ServiceModel.BasicHttpBinding.MaxReceivedMessageSize of MaxReceivedMessageSize). De maxAllowedContentLength eigenschap is standaard ingesteld op 28,6 MB en de maxReceivedMessageSize eigenschap is standaard ingesteld op 64 kB.

Coderingen

Een codering definieert een set regels voor het presenteren van berichten op de kabel. Een encoder implementeert een dergelijke codering en is verantwoordelijk voor het omzetten van een in-memory Message in een bytestroom of bytebuffer die via het netwerk kan worden verzonden. Aan de ontvangerzijde verandert de encoder een reeks bytes in een in-memory bericht.

WCF bevat drie encoders en stelt u in staat om uw eigen encoders te schrijven en in te pluggen, indien nodig.

Elk van de standaardbindingen bevat een vooraf geconfigureerde encoder, waarbij de bindingen met het Net*-voorvoegsel gebruikmaken van het binaire coderingsprogramma (door inclusief de BinaryMessageEncodingBindingElement klasse) terwijl de BasicHttpBinding en WSHttpBinding klassen standaard gebruikmaken van de coderingsprogramma voor tekstberichten (door middel van de TextMessageEncodingBindingElement klasse).

Bindingselement voor encoders Beschrijving
TextMessageEncodingBindingElement De encoder voor tekstberichten is de standaardcoderingsprogramma voor alle HTTP-bindingen en de juiste keuze voor alle aangepaste bindingen, waarbij interoperabiliteit het grootste probleem is. Deze encoder leest en schrijft standaard SOAP 1.1/SOAP 1.2-tekstberichten zonder speciale verwerking voor binaire gegevens. Als de System.ServiceModel.Channels.MessageVersion eigenschap van een bericht is ingesteld op MessageVersion.None, wordt de SOAP-envelopwikkelaar weggelaten uit de uitvoer en wordt alleen de inhoud van de berichttekst geserialiseerd.
MtomMessageEncodingBindingElement De MTOM-berichtcoderingsprogramma is een tekstcoderingsprogramma dat speciale verwerking voor binaire gegevens implementeert en niet standaard wordt gebruikt in een van de standaardbindingen, omdat het strikt een hulpprogramma voor case-by-case-optimalisatie is. Als het bericht binaire gegevens bevat die een drempelwaarde overschrijden waarbij MTOM-codering een voordeel oplevert, worden de gegevens ge externaliseerd in een MIME-onderdeel na de berichtenvelop. Zie MTOM inschakelen verderop in deze sectie.
BinaryMessageEncodingBindingElement De binaire berichtcoderingsprogramma is de standaardcoderingsprogramma voor de Net*-bindingen en de juiste keuze wanneer beide communicerende partijen zijn gebaseerd op WCF. De binaire berichtcoderingsprogramma maakt gebruik van de .NET Binaire XML-indeling, een Microsoft-specifieke binaire weergave voor XML-gegevenssets (Infosets) die over het algemeen een kleinere footprint oplevert dan de equivalente XML 1.0-weergave en codeert binaire gegevens als een bytestroom.

Tekstberichtcodering is doorgaans de beste keuze voor elk communicatiepad waarvoor interoperabiliteit is vereist, terwijl binaire berichtcodering de beste keuze is voor elk ander communicatiepad. Binaire berichtcodering levert doorgaans kleinere berichtgrootten op in vergelijking met tekst voor één bericht en geleidelijk nog kleinere berichtgrootten gedurende de duur van een communicatiesessie. In tegenstelling tot tekstcodering hoeft binaire codering geen speciale verwerking te gebruiken voor binaire gegevens, zoals het gebruik van Base64, maar bytes als bytes.

Als uw oplossing geen interoperabiliteit vereist, maar u toch HTTP-transport wilt gebruiken, kunt u de BinaryMessageEncodingBindingElement interoperabiliteit opstellen in een aangepaste binding die gebruikmaakt van de HttpTransportBindingElement klasse voor het transport. Als voor een aantal clients in uw service interoperabiliteit is vereist, is het raadzaam om parallelle eindpunten beschikbaar te maken waarvoor elk de juiste transport- en coderingskeuzen heeft voor de respectieve clients.

MTOM inschakelen

Wanneer interoperabiliteit een vereiste is en grote binaire gegevens moeten worden verzonden, is MTOM-berichtcodering de alternatieve coderingsstrategie die u op de standaard BasicHttpBinding of WSHttpBinding bindingen kunt inschakelen door de respectieve MessageEncoding eigenschap in te Mtom stellen op of door de MtomMessageEncodingBindingElement in een CustomBinding. De volgende voorbeeldcode, geëxtraheerd uit het voorbeeld van MTOM-codering , laat zien hoe u MTOM kunt inschakelen in de configuratie.

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

Zoals eerder vermeld, is de beslissing om MTOM-codering te gebruiken, afhankelijk van het gegevensvolume dat u verzendt. Omdat MTOM is ingeschakeld op bindingsniveau, is het inschakelen van MTOM van invloed op alle bewerkingen op een bepaald eindpunt.

Omdat de MTOM-encoder altijd een MTOM-gecodeerd MIME-/multionderdeelbericht verzendt, ongeacht of binaire gegevens worden ge externaliseerd, moet u in het algemeen alleen MTOM inschakelen voor eindpunten die berichten uitwisselen met meer dan 1 kB binaire gegevens. Bovendien moeten de servicecontracten die zijn ontworpen voor gebruik met MTOM-eindpunten, indien mogelijk worden beperkt tot het opgeven van dergelijke gegevensoverdrachtbewerkingen. Gerelateerde besturingsfunctionaliteit moet zich in een afzonderlijk contract bevinden. Deze regel voor alleen MTOM is alleen van toepassing op berichten die worden verzonden via een eindpunt met MTOM-functionaliteit; de MTOM-encoder kan ook binnenkomende niet-MTOM-berichten decoderen en parseren.

Het gebruik van de MTOM-encoder voldoet aan alle andere WCF-functies. Houd er rekening mee dat het mogelijk is om deze regel in alle gevallen te observeren, bijvoorbeeld wanneer sessieondersteuning is vereist.

Programmeermodel

Ongeacht welke van de drie ingebouwde encoders u in uw toepassing gebruikt, is de programmeerervaring identiek met betrekking tot het overdragen van binaire gegevens. Het verschil is hoe WCF de gegevens verwerkt op basis van hun gegevenstypen.

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

Wanneer u MTOM gebruikt, wordt het voorgaande gegevenscontract geserialiseerd volgens de volgende regels:

  • Als binaryBuffer dit niet null en afzonderlijk voldoende gegevens bevat om de MTOM externalization overhead (MIME-headers, enzovoort) te rechtvaardigen in vergelijking met Base64-codering, worden de gegevens ge externaliseerd en meegenomen met het bericht als een binair MIME-onderdeel. Als de drempelwaarde niet wordt overschreden, worden de gegevens gecodeerd als Base64.

  • De tekenreeks (en alle andere typen die niet binair zijn) wordt altijd weergegeven als een tekenreeks in de berichttekst, ongeacht de grootte.

Het effect op de MTOM-codering is hetzelfde of u een expliciet gegevenscontract gebruikt, zoals wordt weergegeven in het vorige voorbeeld, een parameterlijst in een bewerking gebruiken, geneste gegevenscontracten hebben of een gegevenscontractobject overdragen in een verzameling. Bytematrices zijn altijd kandidaten voor optimalisatie en worden geoptimaliseerd als aan de drempelwaarden voor optimalisatie wordt voldaan.

Notitie

U mag geen afgeleide typen in gegevenscontracten gebruiken System.IO.Stream . Streamgegevens moeten worden gecommuniceerd met behulp van het streamingmodel, zoals wordt uitgelegd in de volgende sectie Streaminggegevens.

Streaminggegevens

Wanneer u een grote hoeveelheid gegevens hebt die moet worden overgedragen, is de streamingoverdrachtmodus in WCF een haalbaar alternatief voor het standaardgedrag van het bufferen en verwerken van berichten in het geheugen in zijn geheel.

Zoals eerder vermeld, schakelt u streaming alleen in voor grote berichten (met tekst of binaire inhoud) als de gegevens niet kunnen worden gesegmenteerd, als het bericht tijdig moet worden bezorgd of als de gegevens nog niet volledig beschikbaar zijn wanneer de overdracht wordt gestart.

Beperkingen

U kunt geen aanzienlijk aantal WCF-functies gebruiken wanneer streaming is ingeschakeld:

  • Digitale handtekeningen voor de hoofdtekst van het bericht kunnen niet worden uitgevoerd omdat hiervoor een hash moet worden gebruikt voor de volledige inhoud van het bericht. Met streaming is de inhoud niet volledig beschikbaar wanneer de berichtkoppen worden gemaakt en verzonden en daarom kan een digitale handtekening niet worden berekend.

  • Versleuteling is afhankelijk van digitale handtekeningen om te controleren of de gegevens correct zijn gereconstrueerd.

  • Betrouwbare sessies moeten verzonden berichten op de client bufferen om opnieuw te worden uitgevoerd als een bericht verloren gaat in overdracht en berichten in de service moet bewaren voordat ze aan de serviceimplementatie worden verzonden om de berichtvolgorde te behouden voor het geval berichten buiten de volgorde worden ontvangen.

Vanwege deze functionele beperkingen kunt u alleen beveiligingsopties op transportniveau gebruiken voor streaming en kunt u betrouwbare sessies niet inschakelen. Streaming is alleen beschikbaar met de volgende door het systeem gedefinieerde bindingen:

Omdat de onderliggende transporten van NetTcpBinding en NetNamedPipeBinding inherente betrouwbare leverings- en verbindingsgebaseerde sessieondersteuning hebben, in tegenstelling tot HTTP, worden deze twee bindingen slechts minimaal beïnvloed door deze beperkingen, in de praktijk.

Streaming is niet beschikbaar met het MSMQ-transport (Message Queuing) en kan dus niet worden gebruikt met de NetMsmqBinding of de MsmqIntegrationBinding klasse. Het Message Queuing-transport ondersteunt alleen gebufferde gegevensoverdrachten met een beperkte berichtgrootte, terwijl alle andere transporten geen praktische berichtgroottelimiet hebben voor de meeste scenario's.

Streaming is ook niet beschikbaar bij het gebruik van het Peer Channel-transport, dus is niet beschikbaar met de NetPeerTcpBinding.

Streaming en sessies

Mogelijk krijgt u onverwacht gedrag bij het streamen van oproepen met een binding op basis van een sessie. Alle streaming-aanroepen worden gedaan via één kanaal (het datagramkanaal) dat geen ondersteuning biedt voor sessies, zelfs niet als de binding die wordt gebruikt, is geconfigureerd voor het gebruik van sessies. Als meerdere clients streaming-aanroepen naar hetzelfde serviceobject uitvoeren via een sessiebinding en de gelijktijdigheidsmodus van het serviceobject is ingesteld op enkel en de contextmodus van het exemplaar is ingesteld op PerSession, moeten alle aanroepen het datagramkanaal doorlopen en dus slechts één aanroep tegelijk worden verwerkt. Een of meer clients kunnen dan een time-out uitvoeren. U kunt dit probleem omzeilen door de contextmodus van het serviceobject in te stellen op PerCall of Gelijktijdigheid op Meerdere.

Notitie

MaxConcurrentSessions heeft in dit geval geen effect omdat er slechts één sessie beschikbaar is.

Streaming inschakelen

U kunt streaming op de volgende manieren inschakelen:

  • Aanvragen verzenden en accepteren in de streamingmodus en antwoorden accepteren en retourneren in de buffermodus (StreamedRequest).

  • Verzend en accepteer aanvragen in de buffermodus en accepteer en retourneer antwoorden in de gestreamde modus (StreamedResponse).

  • Aanvragen en antwoorden verzenden en ontvangen in de gestreamde modus in beide richtingen. (Streamed).

U kunt streaming uitschakelen door de overdrachtsmodus in te Bufferedstellen op , wat de standaardinstelling is voor alle bindingen. De volgende code laat zien hoe u de overdrachtsmodus instelt in de configuratie.

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

Wanneer u een instantie maakt van de binding in code, moet u de respectieve TransferMode eigenschap van de binding (of het transportbindingselement als u een aangepaste binding opstelt) instellen op een van de eerder genoemde waarden.

U kunt streaming inschakelen voor aanvragen en antwoorden of voor beide richtingen onafhankelijk aan beide zijden van de communicerende partijen zonder dat dit van invloed is op de functionaliteit. U moet er echter altijd van uitgaan dat de overgedragen gegevensgrootte zo belangrijk is dat het inschakelen van streaming gerechtvaardigd is voor beide eindpunten van een communicatiekoppeling. Voor platformoverschrijdende communicatie waarbij een van de eindpunten niet wordt geïmplementeerd met WCF, is de mogelijkheid om streaming te gebruiken afhankelijk van de streamingmogelijkheden van het platform. Een andere zeldzame uitzondering kan een scenario met geheugenverbruik zijn waarbij een client of service de werkset moet minimaliseren en alleen kleine buffergrootten kan betalen.

Asynchrone streaming inschakelen

Als u asynchrone streaming wilt inschakelen, voegt u het DispatcherSynchronizationBehavior eindpuntgedrag toe aan de servicehost en stelt u de eigenschap in AsynchronousSendEnabled op true. We hebben ook de mogelijkheid toegevoegd van echte asynchrone streaming aan de verzendzijde. Dit verbetert de schaalbaarheid van de service in scenario's waarin het streaming-berichten naar meerdere clients zijn waarvan sommige traag zijn in het lezen, mogelijk vanwege netwerkcongestie of helemaal niet worden gelezen. In deze scenario's blokkeren we nu geen afzonderlijke threads op de service per client. Dit zorgt ervoor dat de service veel meer clients kan verwerken, waardoor de schaalbaarheid van de service wordt verbeterd.

Programmeermodel voor streamed transfers

Het programmeermodel voor streaming is eenvoudig. Geef voor het ontvangen van gestreamde gegevens een bewerkingscontract op met één Stream getypeerde invoerparameter. Retourneer een Stream verwijzing voor het retourneren van gestreamde gegevens.

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

De bewerking Echo in het voorgaande voorbeeld ontvangt en retourneert een stroom en moet daarom worden gebruikt voor een binding met Streamed. Voor de bewerking RequestInfois het StreamedResponse meest geschikt, omdat deze alleen een Stream. De eenrichtingsbewerking is het meest geschikt voor StreamedRequest.

Als u een tweede parameter toevoegt aan de volgende Echo of ProvideInfo bewerkingen, wordt het servicemodel teruggezet naar een gebufferde strategie en wordt de runtime-serialisatieweergave van de stream gebruikt. Alleen bewerkingen met één invoerstroomparameter zijn compatibel met end-to-end aanvraagstreaming.

Deze regel is op dezelfde manier van toepassing op berichtcontracten. Zoals wordt weergegeven in het volgende berichtcontract, kunt u slechts één hoofdtekstlid hebben in uw berichtcontract dat een stream is. Als u aanvullende informatie met de stroom wilt communiceren, moet deze informatie worden meegenomen in berichtkoppen. De hoofdtekst van het bericht is exclusief gereserveerd voor de stream-inhoud.

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

Gestreamde overdrachten eindigen en het bericht wordt gesloten wanneer de stream het einde van het bestand (EOF) bereikt. Wanneer u een bericht verzendt (een waarde retourneert of een bewerking aanroept), kunt u een FileStream en de WCF-infrastructuur vervolgens alle gegevens uit die stream ophalen totdat de stream volledig is gelezen en EOF is bereikt. Als u gestreamde gegevens wilt overdragen voor de bron die geen dergelijke vooraf gebouwde Stream afgeleide klasse bestaat, maakt u een dergelijke klasse, overlayt u die klasse over de streambron en gebruikt u deze als argument of retourwaarde.

Wanneer u een bericht ontvangt, bouwt WCF een stroom over de inhoud van de met Base64 gecodeerde berichttekst (of het respectieve MIME-onderdeel als u MTOM gebruikt) en bereikt de stream EOF wanneer de inhoud is gelezen.

Streaming op transportniveau werkt ook met elk ander type berichtcontract (parameterlijsten, argumenten voor gegevenscontract en expliciet berichtcontract), maar omdat de serialisatie en deserialisatie van dergelijke getypte berichten buffering door de serialisatie vereist, is het gebruik van dergelijke contractvarianten niet raadzaam.

Speciale beveiligingsoverwegingen voor grote gegevens

Met alle bindingen kunt u de grootte van inkomende berichten beperken om denial-of-service-aanvallen te voorkomen. De BasicHttpBindingeigenschap System.ServiceModel.BasicHttpBinding.MaxReceivedMessageSize geeft bijvoorbeeld de grootte van het binnenkomende bericht weer en begrenst dus ook de maximale hoeveelheid geheugen die wordt geopend bij het verwerken van het bericht. Deze eenheid is ingesteld in bytes met een standaardwaarde van 65.536 bytes.

Een beveiligingsrisico dat specifiek is voor het scenario voor het streamen van grote gegevens, veroorzaakt een denial of service doordat gegevens worden gebufferd wanneer de ontvanger verwacht dat deze wordt gestreamd. WCF buffert bijvoorbeeld altijd de SOAP-headers van een bericht, zodat een aanvaller een groot schadelijk bericht kan maken dat volledig uit headers bestaat om ervoor te zorgen dat de gegevens worden gebufferd. Wanneer streaming is ingeschakeld, kan de MaxReceivedMessageSize waarde worden ingesteld op een extreem grote waarde, omdat de ontvanger nooit verwacht dat het hele bericht in het geheugen tegelijk wordt gebufferd. Als WCF wordt gedwongen om het bericht te bufferen, treedt er een overloop van het geheugen op.

Daarom is het beperken van de maximale grootte van binnenkomende berichten in dit geval niet voldoende. De MaxBufferSize eigenschap is vereist om het geheugen te beperken dat WCF-buffers gebruiken. Het is belangrijk om dit in te stellen op een veilige waarde (of deze op de standaardwaarde te houden) bij het streamen. Stel dat uw service bestanden van maximaal 4 GB moet ontvangen en deze op de lokale schijf moet opslaan. Stel ook dat uw geheugen zodanig is beperkt dat u slechts 64 kB aan gegevens tegelijk kunt bufferen. Vervolgens stelt u de in MaxReceivedMessageSize op 4 GB en MaxBufferSize op 64 kB. In uw service-implementatie moet u er ook voor zorgen dat u alleen-lezen uit de binnenkomende stream in segmenten van 64 kB en niet het volgende segment leest voordat het vorige segment naar de schijf is geschreven en uit het geheugen is verwijderd.

Het is ook belangrijk om te begrijpen dat dit quotum alleen de buffering beperkt die door WCF wordt uitgevoerd en u niet kunt beschermen tegen buffering die u in uw eigen service- of client-implementatie uitvoert. Zie Beveiligingsoverwegingen voor gegevens voor meer informatie over aanvullende beveiligingsoverwegingen.

Notitie

De beslissing om gebufferde of gestreamde overdrachten te gebruiken, is een lokale beslissing van het eindpunt. Voor HTTP-transporten wordt de overdrachtsmodus niet doorgegeven via een verbinding of proxyservers en andere tussenpersonen. Het instellen van de overdrachtsmodus wordt niet weergegeven in de beschrijving van de service-interface. Nadat u een WCF-client naar een service hebt gegenereerd, moet u het configuratiebestand bewerken voor services die zijn bedoeld voor gebruik met gestreamde overdrachten om de modus in te stellen. Voor TCP- en benoemde pijptransporten wordt de overdrachtsmodus doorgegeven als een beleidsverklaring.

Zie ook