常常被問到,ASP.NET 的應用程式是否可以共用 Session?我之前的答案一律是「不行」,但真的不行嗎?其實是可以的,只是很難實作。現在,應用 Windows Server AppFabric 的 Cache 功能,就可以達到這樣的境界。
環境
使用上次介紹的建立 AppFabric Cache Cluster,就可以建立起 Windows Server AppFabric 的環境。
測試網頁
首先,建立一個設定/讀取 Session 的網頁。網頁內容如下。
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication3._Default" %> <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent"> </asp:Content> <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent"> <h2> Welcome to ASP.NET! SessionId = <%= Session.SessionID%> </h2> Set value: <asp:TextBox runat="server" ID="txtValue" /> <asp:Button Text="Set Value" runat="server" ID="btnSet" onclick="btnSet_Click" /> <br /> Read value: <asp:Label Text="text" runat="server" ID="lblValue" /> <asp:Button Text="Read Value" runat="server" ID="btnRead" onclick="btnRead_Click" /> <br /> </asp:Content>
而該頁的 CodeBehind 程式如下
using System; namespace WebApplication3 { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void btnSet_Click(object sender, EventArgs e) { Session["value"] = txtValue.Text; } protected void btnRead_Click(object sender, EventArgs e) { lblValue.Text = (string)Session["value"]; } } }
很簡單的程式。按「Set Value」鍵時,將值寫到 Session中,而按「Read Value」鍵時,將值顯示到網頁上。
在 IIS 上,該Application 的名稱為 WebApplication3。以建立 Application 的方式,建立出使用相同路徑但不同應用程式名稱的 WebApplication4。如下圖
未使用 AppFabric 的 Cache 功能時
先打開 WebApplication3 的應用程式 Default.aspx 頁。輸入值為 aaa,再按 Read Value 鍵後,網頁會顯示剛剛輸入的值 aaa。
再打開 WebApplication4的網頁 Default.aspx 頁,按Read Value 鍵,網頁顯示值為空白。
請注意到,即使用相同的Application,不同的 SessionId代表不同的 session,當然會讀到不同的值。雖然是不同的 Application,但有可能有相同SessionId。為了讓測試有意義,此網頁故意將 SessionId 顯示出來。
使用 AppFabric 的 Cache 作為 ASP.NET 的 Session
將 Web.config 修改如下
<?xml version="1.0"?> <configuration> <configSections> <section name="dataCacheClient" type="Microsoft.ApplicationServer.Caching.DataCacheClientSection, Microsoft.ApplicationServer.Caching.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowLocation="true" allowDefinition="Everywhere"/> </configSections> <dataCacheClient> <hosts> <host name="AppFabric1" cachePort="22233"/> </hosts> </dataCacheClient> <system.web> <compilation debug="true" targetFramework="4.0" /> <sessionState mode="Custom" customProvider="AppFabricCacheSessionStoreProvider"> <providers> <add name="AppFabricCacheSessionStoreProvider" type="Microsoft.ApplicationServer.Caching.DataCacheSessionStoreProvider" cacheName="session" sharedId="MyApp"/> </providers> </sessionState> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"/> </system.webServer> </configuration>
此後,如上一測試網頁動作再執行一次。發現可以共用 Session 了。
注意一下,sharedId="MyApp"/ 兩個應用程式都使用相同的 sharedId。如果不同,就是不同的 session 了.
結論
使用 Windows Server AppFabric 的 Cache 作為 ASP.NET 的 Session,除了享有高可用性(High Avaliability)外,也意外地擁有跟應用程式共用 Session 的效果。
但,這樣好處的前提是:需要同一個Session。如果使用打開兩次 Internet Explorer,甚至不同的 browser,就很容易看不到同一個 session 了。
範例程式下載
沒有留言:
張貼留言