Delen via


HttpCookieSession

Het httpCookieSession-voorbeeld laat zien hoe u een aangepast protocolkanaal bouwt voor het gebruik van HTTP-cookies voor sessiebeheer. Dit kanaal maakt communicatie mogelijk tussen WCF-services (Windows Communication Foundation) en ASMX-clients of tussen WCF-clients en ASMX-services.

Wanneer een client een webmethode aanroept in een ASMX-webservice die op een sessie is gebaseerd, doet de ASP.NET-engine het volgende:

  • Hiermee wordt een unieke id (sessie-id) gegenereerd.

  • Hiermee genereert u het sessieobject en koppelt u het aan de unieke id.

  • Voegt de unieke id toe aan een HTTP-antwoordheader voor set-cookies en verzendt deze naar de client.

  • Identificeert de client op volgende aanroepen op basis van de sessie-id die naar de client wordt verzonden.

De client bevat deze sessie-id in de volgende aanvragen voor de server. De server gebruikt de sessie-id van de client om het juiste sessieobject voor de huidige HTTP-context te laden.

HttpCookieSession Channel Message Exchange-patroon

Dit voorbeeld maakt sessies mogelijk voor ASMX-achtige scenario's. Onderaan onze kanaalstack hebben we het HTTP-transport dat ondersteuning biedt IRequestChannel voor en IReplyChannel. Het is de taak van het kanaal om sessies te bieden aan de hogere niveaus van de kanaalstack. In het voorbeeld worden twee kanalen geïmplementeerd, (IRequestSessionChannel en IReplySessionChannel) die ondersteuning bieden voor sessies.

Servicekanaal

Het voorbeeld biedt een servicekanaal in de HttpCookieReplySessionChannelListener klasse. Deze klasse implementeert de IChannelListener interface en converteert het IReplyChannel kanaal van lager in de kanaalstack naar een IReplySessionChannel. Dit proces kan worden onderverdeeld in de volgende onderdelen:

  • Wanneer de kanaallistener wordt geopend, accepteert deze een binnenkanaal van de binnenste listener. Omdat de binnenste listener een datagramlistener is en de levensduur van een geaccepteerd kanaal wordt losgekoppeld van de levensduur van de listener, kunnen we de binnenste listener sluiten en alleen het binnenste kanaal vasthouden

                this.innerChannelListener.Open(timeoutHelper.RemainingTime());
    this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime());
    this.innerChannel.Open(timeoutHelper.RemainingTime());
    this.innerChannelListener.Close(timeoutHelper.RemainingTime());
    
  • Wanneer het geopende proces is voltooid, stellen we een berichtenlus in om berichten van het binnenste kanaal te ontvangen.

    IAsyncResult result = BeginInnerReceiveRequest();
    if (result != null && result.CompletedSynchronously)
    {
       // do not block the user thread
       this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback);
       ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result);
    }
    
  • Wanneer er een bericht binnenkomt, onderzoekt het servicekanaal de sessie-id en de multiplexen naar het juiste sessiekanaal. De kanaallistener onderhoudt een woordenlijst waarmee de sessie-id's worden toegewezen aan de sessiekanaalexemplaren.

    Dictionary<string, IReplySessionChannel> channelMapping;
    

De HttpCookieReplySessionChannel klasse implementeert IReplySessionChannel. Hogere niveaus van de kanaalstack roepen de ReceiveRequest methode aan om aanvragen voor deze sessie te lezen. Elk sessiekanaal heeft een privéberichtwachtrij die wordt gevuld door het servicekanaal.

InputQueue<RequestContext> requestQueue;

In het geval dat iemand de ReceiveRequest methode aanroept en er geen berichten in de berichtenwachtrij staan, wacht het kanaal op een opgegeven hoeveelheid tijd voordat u zichzelf afsluit. Hiermee worden de sessiekanalen opgeschoond die zijn gemaakt voor niet-WCF-clients.

We gebruiken de channelMapping om de ReplySessionChannels, en we sluiten onze onderliggende innerChannel gegevens pas nadat alle geaccepteerde kanalen zijn gesloten. Deze manier HttpCookieReplySessionChannel kan bestaan na de levensduur van HttpCookieReplySessionChannelListener. We hoeven ons ook geen zorgen te maken over het ophalen van garbagecollection onder ons omdat de geaccepteerde kanalen een verwijzing naar hun listener behouden via de OnClosed callback.

Clientkanaal

Het bijbehorende clientkanaal bevindt zich in de HttpCookieSessionChannelFactory klasse. Tijdens het maken van het kanaal verpakt de kanaalfactory het binnenste aanvraagkanaal met een HttpCookieRequestSessionChannel. De HttpCookieRequestSessionChannel klasse stuurt de aanroepen door naar het onderliggende aanvraagkanaal. Wanneer de client de proxy sluit, HttpCookieRequestSessionChannel verzendt u een bericht naar de service die aangeeft dat het kanaal wordt gesloten. Daarom kan de servicekanaalstack het sessiekanaal dat wordt gebruikt, probleemloos afsluiten.

Bindings- en bindingselement

Nadat u de service- en clientkanalen hebt gemaakt, is de volgende stap het integreren ervan in de WCF-runtime. Kanalen worden beschikbaar gesteld aan WCF via bindingen en bindingselementen. Een binding bestaat uit een of meer bindingselementen. WCF biedt verschillende door het systeem gedefinieerde bindingen; Bijvoorbeeld BasicHttpBinding of WSHttpBinding. De HttpCookieSessionBindingElement klasse bevat de implementatie voor het bindingselement. Het overschrijft de methoden voor het maken van de kanaallistener en kanaalfactory om de benodigde kanaallistener- of kanaalfactory-instantiëringen uit te voeren.

In het voorbeeld worden beleidsverklaringen gebruikt voor de servicebeschrijving. Hierdoor kan het voorbeeld de kanaalvereisten publiceren naar andere clients die de service kunnen gebruiken. Met dit bindingselement worden bijvoorbeeld beleidsverklaringen gepubliceerd om potentiële clients te laten weten dat het sessies ondersteunt. Omdat het voorbeeld de ExchangeTerminateMessage eigenschap inschakelt in de configuratie van het bindingselement, worden de benodigde asserties toegevoegd om aan te geven dat de service ondersteuning biedt voor een extra actie voor het uitwisselen van berichten om het sessiegesprek te beëindigen. Clients kunnen deze actie vervolgens gebruiken. De volgende WSDL-code toont de beleidsverklaringen die zijn gemaakt op basis van de 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>

De HttpCookieSessionBinding klasse is een door het systeem geleverde binding die gebruikmaakt van het eerder beschreven bindingselement.

Het kanaal toevoegen aan het configuratiesysteem

Het voorbeeld biedt twee klassen die het voorbeeldkanaal beschikbaar maken via configuratie. De eerste is een BindingElementExtensionElement voor de HttpCookieSessionBindingElement. Het grootste deel van de implementatie wordt gedelegeerd aan de HttpCookieSessionBindingConfigurationElement, die is afgeleid van StandardBindingElement. De HttpCookieSessionBindingConfigurationElement heeft eigenschappen die overeenkomen met de eigenschappen op HttpCookieSessionBindingElement.

Sectie bindingselementextensie

De sectie is een BindingElementExtensionElement sectie HttpCookieSessionBindingElementSection die beschikbaar is voor HttpCookieSessionBindingElement het configuratiesysteem. Met enkele onderdrukkingen wordt de naam van de configuratiesectie vervangen, het type bindingselement en hoe u het bindingselement maakt. Vervolgens kunnen we de extensiesectie als volgt registreren in een configuratiebestand:

<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>

Code testen

Testcode voor het gebruik van dit voorbeeldtransport is beschikbaar in de mappen Client en Service. Het bestaat uit twee tests: één test maakt gebruik van een binding die allowCookies is ingesteld true op de client. Met de tweede test kunt u expliciet afsluiten (met behulp van de beëindigingsberichtuitwisseling) op de binding.

Wanneer u het voorbeeld uitvoert, ziet u de volgende uitvoer:

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.

Het voorbeeld instellen, compileren en uitvoeren

  1. Installeer ASP.NET 4.0 met de volgende opdracht.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd.

  3. Volg de instructies in Het bouwen van de Windows Communication Foundation-voorbeelden om de oplossing te bouwen.

  4. Als u het voorbeeld wilt uitvoeren in een configuratie met één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden.