Anpassade kodare
I det här avsnittet beskrivs hur du skapar anpassade kodare.
I Windows Communication Foundation (WCF) använder du en bindning för att ange hur data ska överföras över ett nätverk mellan slutpunkter. En bindning består av en sekvens med bindningselement. En bindning innehåller valfria protokollbindningselement som säkerhet, ett obligatoriskt meddelandekodarbindningselement och ett obligatoriskt transportbindningselement. En meddelandekodare representeras av ett bindningselement för meddelandekodning. Tre meddelandekodare ingår i WCF: Binary, Message Transmission Optimization Mechanism (MTOM) och Text.
Ett meddelandekodningsbindningselement serialiserar ett utgående Message och skickar det till transporten, eller tar emot den serialiserade formen av ett meddelande från transporten och skickar det till protokollskiktet om det finns, eller till programmet, om det inte finns.
Meddelandekodare transformerar Message instanser till och från en trådrepresentation. Även om kodare beskrivs som sittande ovanför transportlagret i kanalstacken, finns de i transportlagret. Transport (till exempel HTTP) formaterar meddelandet enligt kraven i transportstandarden. Kodare (till exempel text-XML) kodar bara meddelandet.
När du ansluter till en befintlig klient eller server kanske du inte har något val om att använda en viss meddelandekodning. WCF-tjänster kan dock göras tillgängliga via flera slutpunkter, var och en med en annan meddelandekodare. När en enskild kodare inte täcker hela målgruppen för din tjänst kan du överväga att exponera tjänsten över flera slutpunkter. Klientprogram kan sedan välja den slutpunkt som passar dem bäst. Med flera slutpunkter kan du kombinera fördelarna med olika meddelandekodare med andra bindningselement.
Systembaserade kodare
WCF tillhandahåller flera systembaserade bindningar som är utformade för att täcka de vanligaste programscenarierna. Var och en av dessa bindningar kombinerar en transport, meddelandekodare och andra alternativ (säkerhet, till exempel). Det här avsnittet beskriver hur du utökar , Text
Binary
och MTOM
meddelandekodare som ingår i WCF eller skapar en egen anpassad kodare. Textmeddelandekodaren stöder både en vanlig XML-kodning och SOAP-kodningar. Textmeddelandekodarens oformaterade XML-kodningsläge kallas POX-kodaren ("Vanlig gammal XML") för att skilja den från den textbaserade SOAP-kodningen.
Mer information om kombinationerna av bindningselement som tillhandahålls av de systembaserade bindningarna finns i motsvarande avsnitt i Välja en transport.
Så här arbetar du med systembaserade kodare
En kodning läggs till i en bindning med hjälp av en klass som härleds från MessageEncodingBindingElement.
WCF tillhandahåller följande typer av bindningselement som härleds från MessageEncodingBindingElement klassen som kan tillhandahålla text-, binär- och MTOM-kodning (Message Transmission Optimization Mechanism):
TextMessageEncodingBindingElement: Den mest samverkande, men minst effektiva kodaren för XML-meddelanden. En webbtjänst- eller webbtjänstklient kan i allmänhet förstå textbaserad XML. Det är dock inte effektivt att överföra stora block med binära data som text.
BinaryMessageEncodingBindingElement: Representerar bindningselementet som anger teckenkodning och versionshantering av meddelanden som används för binärbaserade XML-meddelanden. Detta är mest effektivt av kodningsalternativen, men det är minst driftskompatibelt, eftersom det endast stöds av WCF-slutpunkter.
MtomMessageEncodingBindingElement: Representerar bindningselementet som anger teckenkodning och versionshantering av meddelanden som används för ett meddelande med hjälp av en MTOM-kodning (Message Transmission Optimization Mechanism). MTOM är en effektiv teknik för överföring av binära data i WCF-meddelanden. MTOM-kodaren försöker balansera mellan effektivitet och samverkan. MTOM-kodningen överför de flesta XML-kodarna i textformat, men optimerar stora block med binära data genom att överföra dem som de är, utan konvertering till text.
Bindningselementet skapar en binär, MTOM eller text MessageEncoderFactory. Fabriken skapar en binär, MTOM- eller textinstans MessageEncoderFactory . Vanligtvis finns det bara en enda instans. Men om sessioner används kan en annan kodare tillhandahållas till varje session. Den binära kodaren använder detta för att samordna dynamiska ordlistor (se XML-infrastruktur).
Metoderna ReadMessage och WriteMessage är kärnan i kodarna. Metoderna tillhandahåller för att läsa ett meddelande från en ström eller från en Byte matris. Bytematriser används när transporten körs i buffrat läge. Meddelanden skrivs alltid till strömmar. Om transporten måste buffrar meddelandet tillhandahåller den en dataström som buffrar.
Resten av medlemmarna arbetar med supportinnehåll, medietyper och MessageVersion. Transporten anropar dessa kodarmetoder för att testa om det inkommande meddelandet kan avkodas av det eller för att avgöra om det utgående meddelandet är giltigt för den här kodaren.
Var och en av de tre kodarimplementeringarna lägger till egenskaper som är relevanta för de specifika kodningarna och som är helt konfigurerbara. Kodarna exponerar också läsarkvoter som har säkra standardvärden. Se XML-infrastruktur för en diskussion om kvoterna.
Funktioner i systembaserade kodare
Det finns ett antal funktioner som tillhandahålls av systemkodarna.
Poolning
Var och en av kodarimplementeringarna försöker poola så mycket som möjligt. Att minska allokeringen är ett viktigt sätt att förbättra prestanda för hanterad kod. Implementeringarna använder SynchronizedPool
klassen för att åstadkomma den här pooleringen. C#-filen innehåller en beskrivning av de ytterligare optimeringar som används av den här klassen.
XmlDictionaryReader och XmlDictionaryWriter instanser poolas och initieras om för att förhindra allokering av nya för varje meddelande. För läsarna återtar ett OnClose
återanrop läsaren när Close()
anropas. Kodaren återvinner också vissa meddelandetillståndsobjekt som används vid konstruerande av meddelanden. Storleken på dessa pooler kan konfigureras av MaxReadPoolSize
egenskaperna och för var och MaxWritePoolSize
en av de tre klasser som härleds från MessageEncodingBindingElement.
Binär kodning
När binär kodning använder sessioner måste den dynamiska ordlistesträngen kommuniceras till mottagaren av meddelandet. Detta görs genom att prefixera meddelandet med de dynamiska ordlistesträngarna. Mottagaren tar bort strängarna, lägger till dem i sessionen och bearbetar meddelandet. Korrekt överföring av ordlistesträngar kräver att transporten buffrades.
Strängarna läggs till i meddelandet med en intern AddSessionInformationToMessage
metod. Den lägger till strängarna som UTF-8 längst fram i meddelandet prefixet med deras längd. Hela ordlisterubriken prefixeras sedan med längden på dess data. Den omvända åtgärden utförs med en intern ExtractSessionInformationFromMessage
metod.
Förutom att bearbeta dynamiska ordlistenycklar tas buffrade sessionskänsliga meddelanden emot på ett unikt sätt. I stället för att skapa en läsare över dokumentet och bearbeta det använder den binära kodaren den interna MessagePatterns
klassen för att dekonstruera den binära dataströmmen. Tanken är att de flesta meddelanden har en viss uppsättning rubriker som visas i en viss ordning när de genereras av WCF. Mönstersystemet delar upp meddelandet baserat på vad det förväntar sig. Om det lyckas initieras ett MessageHeaders objekt utan att XML-koden parsas. Annars återgår den till standardmetoden.
MTOM-kodning
Klassen MtomMessageEncodingBindingElement har ytterligare en konfigurationsegenskap med namnet MaxBufferSize. Detta placerar en övre gräns för hur mycket data som tillåts buffras under processen att läsa ett meddelande. XML-informationsuppsättningen (Infoset) eller andra MIME-delar kan behöva bufferas för att sätta ihop alla MIME-delar i ett enda meddelande.
För att fungera korrekt med HTTP tillhandahåller den interna MTOM-meddelandekodarklassen vissa interna API:er för GetContentType
(som också är interna) och WriteMessage
, som är offentliga och kan åsidosättas. Mer kommunikation måste ske för att säkerställa att värdena i HTTP-huvudena överensstämmer med värdena i MIME-huvudena.
Internt använder MTOM-meddelandekodaren WCF:s textläsare och liknar textkodaren. Den största skillnaden är att den optimerar stora segment av binära eller "binära stora objekt" (BLOB) genom att inte konvertera dem till Base-64-kodning innan de bäddas in i meddelandebytena. I stället sparas dessa BLOB-filer extraherade och refereras till som MIME-bifogade filer.
Skriva en egen kodare
Om du vill implementera en egen anpassad meddelandekodare måste du tillhandahålla anpassade implementeringar av följande abstrakta basklasser:
Konvertering från minnesintern representation av ett meddelande till en representation som kan skrivas till en dataström kapslas in i MessageEncoder klassen, som fungerar som en fabrik för XML-läsare och XML-skrivare som stöder specifika typer av XML-kodningar.
De viktigaste metoderna i den här klassen som du måste åsidosätta är:
WriteMessage som tar ett MessageEncodingBindingElement objekt och skriver det till ett Stream objekt.
ReadMessage som tar ett Stream objekt och en maximal rubrikstorlek och returnerar ett Message objekt.
Det är koden du skriver i dessa metoder som hanterar konverteringen mellan standardtransportprotokollet och din anpassade kodning.
Därefter måste du koda en fabriksklass som skapar din anpassade kodare. Åsidosätt Encoder för att returnera en instans av din anpassade MessageEncoder.
Anslut sedan din anpassade MessageEncoderFactory till bindningselementstacken som används för att konfigurera tjänsten eller klienten genom att åsidosätta CreateMessageEncoderFactory metoden för att returnera en instans av den här fabriken.
Det finns två exempel med WCF som illustrerar den här processen med exempelkod: Anpassad meddelandekodare: Anpassad textkodare och anpassad meddelandekodare: Komprimeringskodare.