Udostępnij za pośrednictwem


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 wysyła do niego.

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łu mamy transport HTTP, który obsługuje i IRequestChannelIReplyChannel. Jest to zadanie kanału, aby zapewnić sesje wyższym poziomom stosu kanału. 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 HttpCookieReplySessionChannelListener klasie . Ta klasa implementuje interfejs i konwertuje IChannelListenerIReplyChannel kanał z dolnej części stosu kanału 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ż odbiornik wewnętrzny jest odbiornikiem datagramu, a okres istnienia zaakceptowanego kanału jest oddzielony od okresu istnienia odbiornika, możemy zamknąć odbiornik wewnętrzny i trzymać się tylko kanału wewnętrznego

                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 de-multipleksy do odpowiedniego kanału sesji. Odbiornik kanału utrzymuje słownik mapujący identyfikatory sesji na wystąpienia kanału sesji.

    Dictionary<string, IReplySessionChannel> channelMapping;
    

Klasa HttpCookieReplySessionChannel implementuje IReplySessionChannelelement . 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 , aby śledzić element , i nie zamykamy naszego bazowego ReplySessionChannelselementu innerChannel , dopóki wszystkie zaakceptowane kanały nie zostaną zamknięte. W ten sposób HttpCookieReplySessionChannel może istnieć poza okresem HttpCookieReplySessionChannelListeneristnienia . Nie musimy również martwić się o odebranie pamięci odbiornika pod nami, ponieważ zaakceptowane kanały zachowują odwołanie do ich odbiornika za pośrednictwem wywołania zwrotnego 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 bezpiecznie zamknąć kanał sesji, który jest używany.

Binding and Binding Element

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 w celu wykonania niezbędnych wystąpień odbiornika kanału lub fabryki kanałów.

W przykładzie użyto asercji zasad dla opisu usługi. Dzięki temu przykład może opublikować wymagania dotyczące kanału innym klientom, którzy mogą korzystać z usługi. Na przykład ten element powiązania publikuje asercji zasad, aby poinformować potencjalnych klientów, że obsługuje sesje. Ponieważ przykład włącza ExchangeTerminateMessage właściwość w konfiguracji elementu powiązania, dodaje niezbędne asercji, aby pokazać, że usługa obsługuje dodatkową akcję wymiany komunikatów w celu zakończenia 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 HttpCookieSessionBindingConfigurationElementklasy , która pochodzi z klasy StandardBindingElement. Ma HttpCookieSessionBindingConfigurationElement właściwości, które odpowiadają właściwościom obiektu HttpCookieSessionBindingElement.

Sekcja rozszerzenia elementu powiązania

Sekcja HttpCookieSessionBindingElementSection jest elementem uwidacznianym BindingElementExtensionElementHttpCookieSessionBindingElement w systemie konfiguracji. Za pomocą kilku przesłonięć nazwę sekcji konfiguracji, typ elementu powiązania i sposób tworzenia elementu powiązania są zdefiniowane. 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 klienta i usługi. Składa się z dwóch testów — jeden test używa powiązania z allowCookies ustawionym na true klienta. Drugi test umożliwia jawne zamknięcie (przy użyciu wymiany komunikatów zakończenia) w powiązaniu.

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

  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 jednorazowej 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 temacie Uruchamianie przykładów programu Windows Communication Foundation.