HttpCookieSession 範例示範如何建置自定義通訊協定通道,以使用 HTTP Cookie 進行會話管理。 此通道可讓您在 Windows Communication Foundation (WCF) 服務和 ASMX 用戶端之間,或 WCF 用戶端與 ASMX 服務之間進行通訊。
當用戶端在以會話為基礎的 ASMX Web 服務中呼叫 Web 方法時,ASP.NET 引擎會執行下列動作:
產生唯一識別碼(會話ID)。
產生會話物件,並將它與唯一標識符產生關聯。
將唯一標識元新增至 Set-Cookie HTTP 回應標頭,並將其傳送至用戶端。
根據用戶端發送的會話標識碼,在後續呼叫中識別用戶端。
用戶端會將此會話標識碼包含在對伺服器的後續要求中。 伺服器會使用用戶端的會話 ID,在當前的 HTTP 內容中載入適當的會話物件。
HttpCookieSession 通道訊息交換模式
此範例會針對類 ASMX 的場景啟用會話。 支援 IRequestChannel 和 IReplyChannel 的 HTTP 傳輸位於我們的通道堆疊底部。 通道的工作是為通道堆疊的較高層級提供工作階段。 這個範例會實作兩個支援工作階段的通道(IRequestSessionChannel 和 IReplySessionChannel。
服務通道
此範例提供 類別中的 HttpCookieReplySessionChannelListener 服務通道。 這個類別實作IChannelListener介面,並將通道堆疊中較低的IReplyChannel通道轉換為IReplySessionChannel。 此程式可以分成下列部分:
當通道監聽器開啟時,它會從其內部監聽器接受內部通道。 由於內部接聽程式是數據報接聽程式,且接受通道的存留期與接聽程式的存留期分離,因此我們可以關閉內部接聽程式,並只保留內部通道
this.innerChannelListener.Open(timeoutHelper.RemainingTime()); this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime()); this.innerChannel.Open(timeoutHelper.RemainingTime()); this.innerChannelListener.Close(timeoutHelper.RemainingTime());當開啟的進程完成時,我們會設定訊息迴圈,以接收來自內部通道的訊息。
IAsyncResult result = BeginInnerReceiveRequest(); if (result != null && result.CompletedSynchronously) { // do not block the user thread this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback); ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result); }當訊息送達時,服務通道會檢查會話識別碼,並將其分配至適當的會話通道。 通道接聽程式會維護將會話標識碼對應至會話通道實例的字典。
Dictionary<string, IReplySessionChannel> channelMapping;
類別 HttpCookieReplySessionChannel 會實作 IReplySessionChannel。 較高層級的通道堆疊會呼叫 ReceiveRequest 方法來讀取此會話的要求。 每個會話通道都有由服務通道填入的私人消息佇列。
InputQueue<RequestContext> requestQueue;
如果有人呼叫 ReceiveRequest 方法,而且消息佇列中沒有任何訊息,通道會在關閉本身之前等候指定的時間量。 這會清除針對非 WCF 用戶端建立的會話通道。
我們會使用 channelMapping 來追蹤 ReplySessionChannels,而且在所有已接受的通道都已關閉之前,我們不會關閉基礎 innerChannel 。 這樣一來,HttpCookieReplySessionChannel 可以存在於 HttpCookieReplySessionChannelListener 的存活期之外。 我們也不必擔心接聽程式收到垃圾收集到我們下方,因為接受的通道會透過 OnClosed 回呼保留其接聽程序的參考。
用戶端通道
對應的用戶端通道位於類別中 HttpCookieSessionChannelFactory 。 在通道建立期間,通道工廠會使用 HttpCookieRequestSessionChannel 封裝內部要求通道。 類別會將 HttpCookieRequestSessionChannel 呼叫轉送至基礎要求通道。 當用戶端關閉 Proxy 時, HttpCookieRequestSessionChannel 將訊息傳送至服務,指出通道正在關閉。 因此,服務通道堆疊可以正常關閉正在使用的會話通道。
綁定和綁定元素
建立服務和用戶端通道之後,下一個步驟是將它們整合到WCF運行時間。 通道會透過系結和綁定項向 WCF 公開。 系結是由一或多個綁定項所組成。 WCF 提供數個系統定義的系結;例如,BasicHttpBinding 或 WSHttpBinding。 類別 HttpCookieSessionBindingElement 包含綁定項的實作。 它會覆寫通道接聽程式和通道處理站建立方法,以執行必要的通道接聽程式或通道處理站具現化。
此範例使用政策宣告來說明服務。 這可讓範例將其通道需求發佈至可取用服務的其他用戶端。 例如,這個綁定項會發佈原則判斷提示,讓潛在用戶端知道它支援會話。 因為範例會啟用 ExchangeTerminateMessage 綁定項組態中的 屬性,所以它會新增必要的判斷提示,以顯示服務支持額外的訊息交換動作來終止會話交談。 用戶端接著可以使用此動作。 下列 WSDL 程式代碼顯示從 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>
類別 HttpCookieSessionBinding 是系統提供的系結,使用先前所述的綁定項。
將通道新增至組態系統
此範例提供了兩個類別,透過設定呈現範例通道。 第一個 BindingElementExtensionElement 是 HttpCookieSessionBindingElement 的。 大部分的實作會委派給衍生自 HttpCookieSessionBindingConfigurationElement 的 StandardBindingElement。
HttpCookieSessionBindingConfigurationElement具有對應至 上HttpCookieSessionBindingElement屬性的屬性。
綁定元素擴充區段
區段 HttpCookieSessionBindingElementSection 是將 BindingElementExtensionElement 公開給組態系統的HttpCookieSessionBindingElement。 透過一些覆寫,可以定義組態區段名稱、綁定元素的類型,及如何建立綁定元素。 然後,我們可以在組態檔中註冊延伸模組區段,如下所示:
<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>
測試程序代碼
用戶端和服務目錄中提供使用此範例傳輸的測試程序代碼。 它是由兩個測試所組成,一個測試會使用在用戶端上設定為 allowCookies 的系結true。 第二個測試會在系結上啟用明確關機(使用終止訊息交換)。
當您執行範例時,應該會看到下列輸出:
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.
要設定、建置和執行範例,請執行以下步驟:
請使用下列命令安裝 ASP.NET 4.0。
%windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable請確定您已針對 Windows Communication Foundation 範例 執行One-Time 安裝程式。
若要建置解決方案,請遵循 建置 Windows Communication Foundation 範例中的指示。
若要在單一或跨計算機組態中執行範例,請遵循執行 Windows Communication Foundation 範例 中的指示。