HttpCookieSession
Exemplet HttpCookieSession visar hur du skapar en anpassad protokollkanal för att använda HTTP-cookies för sessionshantering. Den här kanalen möjliggör kommunikation mellan WCF-tjänster (Windows Communication Foundation) och ASMX-klienter eller mellan WCF-klienter och ASMX-tjänster.
När en klient anropar en webbmetod i en ASMX-webbtjänst som är sessionsbaserad, gör ASP.NET-motorn följande:
Genererar ett unikt ID (sessions-ID).
Genererar sessionsobjektet och associerar det med det unika ID:t.
Lägger till det unika ID:t i ett HTTP-svarshuvud för Set-Cookie och skickar det till klienten.
Identifierar klienten vid efterföljande anrop baserat på det sessions-ID som den skickar till den.
Klienten innehåller det här sessions-ID:t i efterföljande begäranden till servern. Servern använder sessions-ID:t från klienten för att läsa in lämpligt sessionsobjekt för den aktuella HTTP-kontexten.
Exchange-mönster för HttpCookieSession Channel-meddelande
Det här exemplet aktiverar sessioner för ASMX-liknande scenarier. Längst ned i vår kanalstacken har vi HTTP-transporten som stöder IRequestChannel och IReplyChannel. Det är kanalens jobb att tillhandahålla sessioner till de högre nivåerna i kanalstacken. Exemplet implementerar två kanaler, (IRequestSessionChannel och IReplySessionChannel) som stöder sessioner.
Tjänstkanal
Exemplet tillhandahåller en tjänstkanal i HttpCookieReplySessionChannelListener
klassen. Den här klassen implementerar IChannelListener gränssnittet och konverterar IReplyChannel kanalen från lägre i kanalstacken till en IReplySessionChannel. Den här processen kan delas in i följande delar:
När kanallyssnaren öppnas accepterar den en inre kanal från den inre lyssnaren. Eftersom den inre lyssnaren är en datagramlyssnare och livslängden för en accepterad kanal är frikopplad från lyssnarens livslängd kan vi stänga den inre lyssnaren och bara hålla fast vid den inre kanalen
this.innerChannelListener.Open(timeoutHelper.RemainingTime()); this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime()); this.innerChannel.Open(timeoutHelper.RemainingTime()); this.innerChannelListener.Close(timeoutHelper.RemainingTime());
När den öppna processen är klar konfigurerar vi en meddelandeloop för att ta emot meddelanden från den inre kanalen.
IAsyncResult result = BeginInnerReceiveRequest(); if (result != null && result.CompletedSynchronously) { // do not block the user thread this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback); ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result); }
När ett meddelande tas emot undersöker tjänstkanalen sessionsidentifieraren och de-multiplexer till lämplig sessionskanal. Kanallyssnaren har en ordlista som mappar sessionsidentifierarna till sessionskanalinstanserna.
Dictionary<string, IReplySessionChannel> channelMapping;
Klassen HttpCookieReplySessionChannel
implementerar IReplySessionChannel. Högre nivåer av kanalstacken anropar ReceiveRequest metoden för att läsa begäranden för den här sessionen. Varje sessionskanal har en privat meddelandekö som fylls i av tjänstkanalen.
InputQueue<RequestContext> requestQueue;
Om någon anropar ReceiveRequest metoden och det inte finns några meddelanden i meddelandekön väntar kanalen en angiven tid innan den stänger av sig själv. Detta rensar de sessionskanaler som skapats för icke-WCF-klienter.
Vi använder channelMapping
för att spåra ReplySessionChannels
, och vi stänger inte vår underliggande innerChannel
förrän alla godkända kanaler har stängts. Det här sättet HttpCookieReplySessionChannel
kan finnas bortom livslängden för HttpCookieReplySessionChannelListener
. Vi behöver inte heller oroa oss för att lyssnaren får skräp som samlas in under oss eftersom de accepterade kanalerna håller en referens till sin lyssnare genom återanropet OnClosed
.
Klientkanal
Motsvarande klientkanal finns i HttpCookieSessionChannelFactory
klassen . När kanalen skapas omsluter kanalfabriken den inre begärandekanalen med en HttpCookieRequestSessionChannel
. Klassen HttpCookieRequestSessionChannel
vidarebefordrar anropen till den underliggande begärandekanalen. När klienten stänger proxyn HttpCookieRequestSessionChannel
skickar du ett meddelande till tjänsten som anger att kanalen stängs. Därför kan tjänstkanalstacken på ett smidigt sätt stänga av den sessionskanal som används.
Bindnings- och bindningselement
När du har skapat tjänst- och klientkanalerna är nästa steg att integrera dem i WCF-körningen. Kanaler exponeras för WCF via bindningar och bindningselement. En bindning består av ett eller flera bindningselement. WCF erbjuder flera systemdefinierade bindningar; Till exempel BasicHttpBinding eller WSHttpBinding. Klassen HttpCookieSessionBindingElement
innehåller implementeringen för bindningselementet. Den åsidosätter kanallyssnaren och kanalfabrikens skapandemetoder för att göra nödvändiga kanallyssnare eller kanalfabriks-instansieringar.
Exemplet använder principkontroller för tjänstbeskrivningen. På så sätt kan exemplet publicera sina kanalkrav till andra klienter som kan använda tjänsten. Det här bindningselementet publicerar till exempel principkontroller för att låta potentiella klienter veta att det stöder sessioner. Eftersom exemplet aktiverar ExchangeTerminateMessage
egenskapen i konfigurationen av bindningselementet lägger den till de nödvändiga försäkran för att visa att tjänsten stöder en extra meddelandeutbytesåtgärd för att avsluta sessionskonversationen. Klienter kan sedan använda den här åtgärden. Följande WSDL-kod visar de principkontroller som skapats från HttpCookieSessionBindingElement
.
<wsp:Policy wsu:Id="HttpCookieSessionBinding_IWcfCookieSessionService_policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<wspe:Utf816FFFECharacterEncoding xmlns:wspe="http://schemas.xmlsoap.org/ws/2004/09/policy/encoding"/>
<mhsc:httpSessionCookie xmlns:mhsc="http://samples.microsoft.com/wcf/mhsc/policy"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
Klassen HttpCookieSessionBinding
är en systembaserad bindning som använder bindningselementet som beskrevs tidigare.
Lägga till kanalen i konfigurationssystemet
Exemplet innehåller två klasser som exponerar exempelkanalen via konfigurationen. Den första är en BindingElementExtensionElement för HttpCookieSessionBindingElement
. Huvuddelen av implementeringen delegeras till HttpCookieSessionBindingConfigurationElement
, som härleds från StandardBindingElement. Har HttpCookieSessionBindingConfigurationElement
egenskaper som motsvarar egenskaperna på HttpCookieSessionBindingElement
.
Avsnitt för bindningselementtillägg
Avsnittet HttpCookieSessionBindingElementSection
är ett BindingElementExtensionElement som exponeras HttpCookieSessionBindingElement
för konfigurationssystemet. Med några åsidosättningar definieras namnet på konfigurationsavsnittet, typen av bindningselement och hur du skapar bindningselementet. Sedan kan vi registrera tillägget i en konfigurationsfil på följande sätt:
<configuration>
<system.serviceModel>
<extensions>
<bindingElementExtensions>
<add name="httpCookieSession"
type=
"Microsoft.ServiceModel.Samples.HttpCookieSessionBindingElementElement,
HttpCookieSessionExtension, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null"/>
</bindingElementExtensions >
</extensions>
<bindings>
<customBinding>
<binding name="allowCookiesBinding">
<textMessageEncoding messageVersion="Soap11WSAddressing10" />
<httpCookieSession sessionTimeout="10" exchangeTerminateMessage="true" />
<httpTransport allowCookies="true" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
</configuration>
Testkod
Testkod för att använda den här exempeltransporten finns i klient- och tjänstkatalogerna. Den består av två tester – ett test använder en bindning med allowCookies
inställd true
på på klienten. Det andra testet aktiverar explicit avstängning (med hjälp av utväxlingen av avsluta meddelanden) på bindningen.
När du kör exemplet bör du se följande utdata:
Simple binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3
Smart binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3
Press <ENTER> to terminate client.
Så här konfigurerar du, skapar och kör exemplet
Installera ASP.NET 4.0 med hjälp av följande kommando.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
Kontrollera att du har utfört engångsinstallationsproceduren för Windows Communication Foundation-exempel.
Skapa lösningen genom att följa anvisningarna i Skapa Windows Communication Foundation-exempel.
Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel.