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 ReplySessionChannels
elementu innerChannel
, dopóki wszystkie zaakceptowane kanały nie zostaną zamknięte. W ten sposób HttpCookieReplySessionChannel
może istnieć poza okresem HttpCookieReplySessionChannelListener
istnienia . 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 HttpCookieSessionBindingConfigurationElement
klasy , 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
Zainstaluj ASP.NET 4.0 przy użyciu następującego polecenia.
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
Upewnij się, że wykonano procedurę instalacji jednorazowej dla przykładów programu Windows Communication Foundation.
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).
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.