Udostępnij przez


HttpCookieSession

Przykład HttpCookieSession pokazuje, jak utworzyć niestandardowy kanał protokołu do używania plików cookie HTTP na potrzeby zarządzania sesjami. Ten kanał umożliwia komunikację między usługami Windows Communication Foundation (WCF) i klientami ASMX lub między klientami programu WCF i usługami ASMX.

Gdy klient wywołuje metodę sieci Web w usłudze sieci Web ASMX opartej na sesji, aparat ASP.NET wykonuje następujące czynności:

  • Generuje unikatowy identyfikator (identyfikator sesji).

  • Generuje obiekt sesji i kojarzy go z unikatowym identyfikatorem.

  • Dodaje unikatowy identyfikator do nagłówka odpowiedzi HTTP Set-Cookie i wysyła go do klienta.

  • Identyfikuje klienta na kolejnych wywołaniach na podstawie identyfikatora sesji, który do niego przesyła.

Klient zawiera ten identyfikator sesji w kolejnych żądaniach do serwera. Serwer używa identyfikatora sesji od klienta do załadowania odpowiedniego obiektu sesji dla bieżącego kontekstu HTTP.

Wzorzec wymiany komunikatów kanału HttpCookieSession

Ten przykład umożliwia sesje dla scenariuszy przypominających ASMX. W dolnej części naszego stosu kanałów mamy transport HTTP, który obsługuje IRequestChannel i IReplyChannel. Jest to zadanie kanału, aby dostarczać sesje wyższym poziomom stosu kanałowego. Przykład implementuje dwa kanały (IRequestSessionChannel i IReplySessionChannel), które obsługują sesje.

Kanał usługi

Przykład udostępnia kanał usługi w klasie HttpCookieReplySessionChannelListener. Ta klasa implementuje interfejs IChannelListener i konwertuje kanał IReplyChannel z dolnej części stosu kanałów na IReplySessionChannel. Ten proces można podzielić na następujące części:

  • Po otwarciu odbiornika kanału akceptuje kanał wewnętrzny z odbiornika wewnętrznego. Ponieważ wewnętrzny nasłuchiwacz jest nasłuchiwaczem datagramów, a czas życia zaakceptowanego kanału jest oddzielony od czasu życia nasłuchiwacza, możemy zamknąć wewnętrzny nasłuchiwacz i utrzymywać tylko wewnętrzny kanał.

                this.innerChannelListener.Open(timeoutHelper.RemainingTime());
    this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime());
    this.innerChannel.Open(timeoutHelper.RemainingTime());
    this.innerChannelListener.Close(timeoutHelper.RemainingTime());
    
  • Po zakończeniu procesu otwierania skonfigurujemy pętlę komunikatów w celu odbierania komunikatów z kanału wewnętrznego.

    IAsyncResult result = BeginInnerReceiveRequest();
    if (result != null && result.CompletedSynchronously)
    {
       // do not block the user thread
       this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback);
       ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result);
    }
    
  • Po nadejściu komunikatu kanał usługi sprawdza identyfikator sesji i demultipleksuje do odpowiedniego kanału sesji. Odbiornik kanału utrzymuje słownik mapujący identyfikatory sesji do wystąpień kanału sesji.

    Dictionary<string, IReplySessionChannel> channelMapping;
    

Klasa HttpCookieReplySessionChannel implementuje IReplySessionChannel. Wyższe poziomy stosu kanału wywołają metodę ReceiveRequest w celu odczytania żądań dla tej sesji. Każdy kanał sesji ma prywatną kolejkę komunikatów wypełnianą przez kanał usługi.

InputQueue<RequestContext> requestQueue;

W przypadku, gdy ktoś wywołuje metodę ReceiveRequest i nie ma żadnych komunikatów w kolejce komunikatów, kanał czeka przez określony czas przed zamknięciem się. Spowoduje to wyczyszczenie kanałów sesji utworzonych dla klientów innych niż WCF.

Używamy elementu channelMapping do śledzenia ReplySessionChannels, i nie zamykamy naszego bazowego innerChannel dopóki wszystkie zaakceptowane kanały nie zostaną zamknięte. W ten sposób HttpCookieReplySessionChannel może istnieć poza okresem istnienia HttpCookieReplySessionChannelListener. Nie musimy również martwić się o nieoczekiwaną kolekcję śmieci słuchacza, ponieważ zaakceptowane kanały zachowują do niego odwołanie poprzez wywołanie zwrotne OnClosed.

Kanał klienta

Odpowiedni kanał klienta znajduje się w HttpCookieSessionChannelFactory klasie . Podczas tworzenia kanału fabryka kanałów opakowuje wewnętrzny kanał żądania za pomocą elementu HttpCookieRequestSessionChannel. Klasa HttpCookieRequestSessionChannel przekazuje wywołania do bazowego kanału żądania. Gdy klient zamknie serwer proxy, HttpCookieRequestSessionChannel wysyła komunikat do usługi, który wskazuje, że kanał jest zamykany. W związku z tym stos kanału usługi może płynnie zamknąć kanał sesji, który jest używany.

Więzy i Element Wiązania

Po utworzeniu kanałów usługi i klienta następnym krokiem jest zintegrowanie ich ze środowiskiem uruchomieniowym WCF. Kanały są udostępniane w programie WCF za pośrednictwem powiązań i elementów powiązania. Powiązanie składa się z jednego lub wielu elementów powiązania. Program WCF oferuje kilka powiązań zdefiniowanych przez system; na przykład BasicHttpBinding lub WSHttpBinding. Klasa HttpCookieSessionBindingElement zawiera implementację elementu powiązania. Zastępuje metody tworzenia odbiornika kanału i fabryki kanałów, aby zrealizować konieczne tworzenie odbiornika kanału lub fabryki kanałów.

W przykładzie użyto deklaracji polityk do opisania usługi. Dzięki temu przykład może udostępnić wymagania dotyczące kanału innym klientom, którzy mogą korzystać z tej usługi. Na przykład ten element powiązania publikuje asercje zasad, aby poinformować potencjalnych klientów, że obsługuje sesje. Ponieważ przykład włącza właściwość ExchangeTerminateMessage w konfiguracji elementu powiązania, dodaje niezbędne asercje, aby pokazać, że usługa obsługuje dodatkową akcję wymiany komunikatów, umożliwiając zakończenie konwersacji sesji. Klienci mogą następnie użyć tej akcji. Poniższy kod WSDL przedstawia asercji zasad utworzone na podstawie elementu 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>

Klasa HttpCookieSessionBinding jest powiązaniem dostarczonym przez system, które używa opisanego wcześniej elementu powiązania.

Dodawanie kanału do systemu konfiguracji

Przykład zawiera dwie klasy, które uwidaczniają przykładowy kanał za pośrednictwem konfiguracji. Pierwszy to element BindingElementExtensionElement dla elementu HttpCookieSessionBindingElement. Większość implementacji jest delegowana do HttpCookieSessionBindingConfigurationElement, który pochodzi z StandardBindingElement. Właściwości HttpCookieSessionBindingConfigurationElement odpowiadają właściwościom HttpCookieSessionBindingElement.

Sekcja rozszerzeń funkcji elementów wiążących

Sekcja HttpCookieSessionBindingElementSection jest elementem uwidacznianym BindingElementExtensionElementHttpCookieSessionBindingElement w systemie konfiguracji. Za pomocą kilku modyfikacji można zdefiniować nazwę sekcji konfiguracji, typ elementu powiązania oraz sposób jego tworzenia. Następnie możemy zarejestrować sekcję rozszerzenia w pliku konfiguracji w następujący sposób:

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

Kod testowy

Kod testowy do korzystania z tego przykładowego transportu jest dostępny w katalogach Klient i Usługi. Składa się z dwóch testów — jeden z testów wykorzystuje powiązanie, w którym allowCookies jest ustawione na true na kliencie. Drugi test umożliwia jawne zakończenie (poprzez wymianę komunikatów zakończenia) w połączeniu.

Po uruchomieniu przykładu powinny zostać wyświetlone następujące dane wyjściowe:

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.

Aby skonfigurować, skompilować i uruchomić przykładowy program

  1. Zainstaluj ASP.NET 4.0 przy użyciu następującego polecenia.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Upewnij się, że wykonano procedurę instalacji One-Time dla przykładów programu Windows Communication Foundation.

  3. Aby skompilować rozwiązanie, postępuj zgodnie z instrukcjami w temacie Building the Windows Communication Foundation Samples (Tworzenie przykładów programu Windows Communication Foundation).

  4. Aby uruchomić przykład w konfiguracji pojedynczej lub między maszynami, postępuj zgodnie z instrukcjami w Uruchamianie przykładów programu Windows Communication Foundation.