HttpCookieSessionHttpCookieSession

In diesem Beispiel wird das Erstellen eines benutzerdefinierten Protokollkanals für die Verwendung von HTTP-Cookies für die Sitzungsverwaltung veranschaulicht.This sample demonstrates how to build a custom protocol channel to use HTTP cookies for session management. Dieser Kanal ermöglicht die Kommunikation zwischen Windows Communication Foundation (WCF)-Dienste und ASMX-Clients oder WCF-Clients und ASMX-Diensten.This channel enables communication between Windows Communication Foundation (WCF) services and ASMX clients or between WCF clients and ASMX services.

Wenn ein Client eine Webmethode in einem sitzungsbasierten ASMX-Webdienst aufruft, führt das ASP.NETASP.NET-Modul Folgendes aus:When a client calls a Web method in an ASMX Web service that is session-based, the ASP.NETASP.NET engine does the following:

  • Generiert eine eindeutige ID (Sitzungs-ID).Generates a unique ID (session ID).

  • Generiert das Sitzungsobjekt und ordnet es der eindeutigen ID zu.Generates the session object and associates it with the unique ID.

  • Fügt die eindeutige ID dem HTTP-Antwortheader Set-Cookie hinzu und sendet diesen an den Client.Adds the unique ID to a Set-Cookie HTTP response header and sends it to the client.

  • Identifiziert den Client in nachfolgenden Aufrufen auf Grundlage der an ihn gesendeten Sitzungs-ID.Identifies the client on subsequent calls based on the session ID it sends to it.

Der Client schließt diese Sitzungs-ID in nachfolgenden Anforderungen an den Server ein.The client includes this session ID in its subsequent requests to the server. Der Server lädt mithilfe der Sitzungs-ID vom Client das entsprechende Sitzungsobjekt für den aktuellen HTTP-Kontext.The server uses the session ID from the client to load the appropriate session object for the current HTTP context.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Extensibility\Channels\HttpCookieSession

HttpCookieSession-Nachrichtenaustauschmuster für KanalHttpCookieSession Channel Message Exchange Pattern

In diesem Beispiel werden Sitzungen für ASMX-ähnliche Szenarios aktiviert.This sample enables sessions for ASMX-like scenarios. Unten im Kanalstapel befindet sich der HTTP-Transport, der IRequestChannel und IReplyChannel unterstützt.At the bottom of our channel stack, we have the HTTP transport that supports IRequestChannel and IReplyChannel. Der Kanal stellt Sitzungen für die höheren Ebenen des Kanalstapels bereit.It is the job of the channel to provide sessions to the higher levels of the channel stack. Im Beispiel werden zwei Kanäle implementiert, die Sitzungen unterstützen (IRequestSessionChannel und IReplySessionChannel).The sample implements two channels, (IRequestSessionChannel and IReplySessionChannel) that support sessions.

DienstkanalService Channel

Im Beispiel wird ein Dienstkanal in der HttpCookieReplySessionChannelListener-Klasse bereitgestellt.The sample provides a service channel in the HttpCookieReplySessionChannelListener class. Diese Klasse implementiert die IChannelListener-Schnittstelle und konvertiert den IReplyChannel-Kanal weiter unten im Kanalstapel in IReplySessionChannel.This class implements the IChannelListener interface and converts the IReplyChannel channel from lower in the channel stack to a IReplySessionChannel. Dieser Prozess kann folgendermaßen unterteilt werden:This process can be divided into the following parts:

  • Wenn der Kanallistener geöffnet wird, akzeptiert er einen inneren Kanal vom inneren Listener.When the channel listener is opened, it accepts an inner channel from its inner listener. Da es sich bei dem inneren Listener um einen Datagrammlistener handelt und die Lebensdauer eines akzeptierten Kanals unabhängig von der Lebensdauer des Listeners ist, kann der innere Listener geschlossen und nur der innere Kanal beibehalten werden.Because the inner listener is a datagram listener and the lifetime of an accepted channel is decoupled from the lifetime of the listener, we can close the inner listener and only hold on to the inner channel

                this.innerChannelListener.Open(timeoutHelper.RemainingTime());  
    this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime());  
    this.innerChannel.Open(timeoutHelper.RemainingTime());  
    this.innerChannelListener.Close(timeoutHelper.RemainingTime());  
    
  • Wenn der Prozess zum Öffnen abgeschlossen ist, wird eine Nachrichtenschleife zum Empfangen von Nachrichten vom inneren Kanal eingerichtet.When the open process completes, we set up a message loop to receive messages from the inner channel.

    IAsyncResult result = BeginInnerReceiveRequest();  
    if (result != null && result.CompletedSynchronously)  
    {  
       // do not block the user thread  
       if (this.completeReceiveCallback == null)  
       {  
          this.completeReceiveCallback = new WaitCallback(CompleteReceiveCallback);  
       }  
       ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result);  
    }  
    
  • Wenn eine Nachricht eingeht, prüft der Dienstkanal die Sitzungs-ID und führt ein De-Multiplexing für den entsprechenden Sitzungskanal durch.When a message arrives, the service channel examines the session identifier and de-multiplexes to the appropriate session channel. Der Kanallistener verwaltet ein Wörterbuch, das die Sitzungs-IDs den Sitzungskanalinstanzen zuordnet.The channel listener maintains a dictionary that maps the session identifiers to the session channel instances.

    Dictionary<string, IReplySessionChannel> channelMapping;  
    

Die HttpCookieReplySessionChannel -Klasse implementiert IReplySessionChannel.The HttpCookieReplySessionChannel class implements IReplySessionChannel. In höheren Ebenen des Kanalstapels wird die ReceiveRequest-Methode aufgerufen, um Anforderungen für diese Sitzung zu lesen.Higher levels of the channel stack call the ReceiveRequest method to read requests for this session. Jeder Sitzungskanal verfügt über eine private Meldungswarteschlange, die vom Dienstkanal aufgefüllt wird.Each session channel has a private message queue that is populated by the service channel.

InputQueue<RequestContext> requestQueue;  

Wenn die ReceiveRequest-Methode aufgerufen wird und sich keine Meldungen in der Meldungswarteschlange befinden, wartet der Kanal für einen angegebenen Zeitraum und beendet sich dann selbst.In the case when someone calls the ReceiveRequest method and there are no messages in the message queue, the channel waits for a specified amount of time before shutting itself down. Dies wird für nicht-WCF-Clients erstellten Sitzungskanäle bereinigt.This cleans up the session channels created for non-WCF clients.

Mit channelMapping wird ReplySessionChannels nachverfolgt. Außerdem wird der zugrunde liegende innerChannel erst geschlossen, wenn alle akzeptierten Kanäle geschlossen wurden.We use the channelMapping to track the ReplySessionChannels, and we do not close our underlying innerChannel until all the accepted channels have been closed. So kann HttpCookieReplySessionChannel über die Lebensdauer von HttpCookieReplySessionChannelListener hinaus vorhanden sein.This way HttpCookieReplySessionChannel can exist beyond the lifetime of HttpCookieReplySessionChannelListener. Außerdem besteht nicht die Gefahr, dass der Listener durch die Garbage Collection entfernt wird, da die akzeptierten Kanäle über den OnClosed-Rückruf einen Verweis auf den Listener beibehalten.We also do not have to worry about the listener getting garbage collected underneath us because the accepted channels keep a reference to their listener through the OnClosed callback.

ClientkanalClient channel

Der entsprechende Clientkanal befindet sich in der HttpCookieSessionChannelFactory-Klasse.The corresponding client channel is in the HttpCookieSessionChannelFactory class. Bei der Kanalerstellung schließt die Kanalfactory den inneren Anforderungskanal mit einem HttpCookieRequestSessionChannel ein.During channel creation, the channel factory wraps the inner request channel with an HttpCookieRequestSessionChannel. Die HttpCookieRequestSessionChannel-Klasse leitet die Aufrufe des zugrunde liegenden Anforderungskanals weiter.The HttpCookieRequestSessionChannel class forwards the calls to the underlying request channel. Wenn der Client den Proxy schließt, sendet HttpCookieRequestSessionChannel eine Meldung an den Dienst, mit der angegeben wird, dass der Kanal geschlossen wird.When the client closes the proxy, HttpCookieRequestSessionChannel sends a message to the service that indicates that the channel is being closed. So kann der Dienstkanalstapel den verwendeten Sitzungskanal ordnungsgemäß beenden.Thus, the service channel stack can gracefully shutdown the session channel that is in use.

Bindung und BindungselementBinding and Binding Element

Als Nächstes werden nach dem Erstellen der Dienst- und Kanäle können sie in der WCF-Laufzeit zu integrieren.After creating the service and client channels, the next step is to integrate them into the WCF runtime. Kanäle werden durch Bindungen und Bindungselemente WCF verfügbar gemacht.Channels are exposed to WCF through bindings and binding elements. Eine Bindung besteht aus einem oder mehreren Bindungselementen.A binding consists of one or many binding elements. WCF bietet mehrere systemdefinierte Bindungen; z. B. "BasicHttpBinding" oder "WSHttpBinding".WCF offers several system-defined bindings; for example, BasicHttpBinding or WSHttpBinding. Die HttpCookieSessionBindingElement-Klasse enthält die Implementierung des Bindungselements.The HttpCookieSessionBindingElement class contains the implementation for the binding element. Sie überschreibt die Methoden zur Kanallistener- und Kanalfactoryerstellung, um die erforderlichen Instanziierungen des Kanallisteners und der Kanalfactory auszuführen.It overrides the channel listener and channel factory creation methods to do the necessary channel listener or channel factory instantiations.

Im Beispiel werden Richtlinienassertionen für die Dienstbeschreibung verwendet.The sample uses policy assertions for the service description. So können im Beispiel die Kanalanforderungen für andere Clients veröffentlicht werden, die den Dienst verwenden können.This allows the sample to publish its channel requirements to other clients that can consume the service. Dieses Bindungselement veröffentlicht beispielsweise Richtlinienassertionen, damit potenzielle Clients wissen, dass Sitzungen unterstützt werden.For example, this binding element publishes policy assertions to let potential clients know that it supports sessions. Da im Beispiel die ExchangeTerminateMessage-Eigenschaft in der Bindungselementkonfiguration aktiviert wird, werden die erforderlichen Assertionen hinzugefügt, um zu zeigen, dass der Dienst eine zusätzliche Meldungsaustauschaktion zum Beenden der Sitzungskommunikation unterstützt.Because the sample enables the ExchangeTerminateMessage property in the binding element configuration, it adds the necessary assertions to show that the service supports an extra message exchange action to terminate the session conversation. Clients können diese Aktion dann verwenden.Clients can then use this action. Im folgenden WSDL-Code werden die aus HttpCookieSessionBindingElement erstellten Richtlinienassertionen veranschaulicht.The following WSDL code shows the policy assertions created from the 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>  

Die HttpCookieSessionBinding-Klasse ist eine vom System bereitgestellte Bindung, die das zuvor beschriebene Bindungselement verwendet.The HttpCookieSessionBinding class is a system-provided binding that uses the binding element described previously.

Hinzufügen des Kanals zum KonfigurationssystemAdding the Channel to the Configuration System

Im Beispiel werden zwei Klassen bereitgestellt, die den Beispielkanal durch Konfiguration verfügbar machen.The sample provides two classes that expose the sample channel through configuration. Die erste ist ein BindingElementExtensionElement für das HttpCookieSessionBindingElement.The first is a BindingElementExtensionElement for the HttpCookieSessionBindingElement. Dem HttpCookieSessionBindingConfigurationElement, das sich von StandardBindingElement herleitet, wird der Großteil der Implementierung übertragen.The bulk of the implementation is delegated to the HttpCookieSessionBindingConfigurationElement, which derives from StandardBindingElement. HttpCookieSessionBindingConfigurationElement verfügt über Eigenschaften, die den Eigenschaften von HttpCookieSessionBindingElement entsprechen.The HttpCookieSessionBindingConfigurationElement has properties that correspond to the properties on HttpCookieSessionBindingElement.

Abschnitt für BindungselementerweiterungenBinding Element Extension Section

Der Abschnitt HttpCookieSessionBindingElementSection ist ein BindingElementExtensionElement, das die HttpCookieSessionBindingElement für das Konfigurationssystem verfügbar macht.The section HttpCookieSessionBindingElementSection is a BindingElementExtensionElement that exposes HttpCookieSessionBindingElement to the configuration system. Mit wenigen Überschreibungen werden der Konfigurationsabschnittsname, der Typ des Bindungselements und das Erstellen des Bindungselements definiert.With a few overrides the configuration section name, the type of the binding element and how to create the binding element are defined. Danach kann der Erweiterungsabschnitt wie folgt in einer Konfigurationsdatei registriert werden:We can then register the extension section in a configuration file as follows:

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

TestcodeTest Code

Testcode für die Verwendung dieses Beispieltransports ist in den Client- und Dienstverzeichnissen verfügbar.Test code for using this sample transport is available in the Client and Service directories. Er besteht aus zwei Tests: ein Test verwendet eine Bindung mit allowCookies festgelegt true auf dem Client.It consists of two tests—one test uses a binding with allowCookies set to true on the client. Im zweiten Test wird das explizite Herunterfahren (mit abschließenden Meldungsaustausch) für die Bindung aktiviert.The second test enables explicit shutdown (using the terminate message exchange) on the binding.

Wenn Sie das Beispiel ausführen, sollten Sie folgende Ausgabe erhalten:When you run the sample, you should see the following output:

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.  

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Installieren Sie ASP.NETASP.NET 4.0 mithilfe des folgenden Befehls.Install ASP.NETASP.NET 4.0 using the following command.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable  
    
  2. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  3. Führen Sie zum Erstellen der Projektmappe die Anweisungen im Erstellen der Windows Communication Foundation-Beispiele.To build the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  4. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

Siehe auchSee Also