2010年9月29日 星期三

Windows Server AppFabric: ASP.NET 4 應用程式共用 Session

常常被問到,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。如下圖

image

未使用 AppFabric 的 Cache 功能時

先打開 WebApplication3 的應用程式 Default.aspx 頁。輸入值為 aaa,再按 Read Value 鍵後,網頁會顯示剛剛輸入的值 aaa。

image

再打開 WebApplication4的網頁 Default.aspx 頁,按Read Value 鍵,網頁顯示值為空白。

image

請注意到,即使用相同的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 了。

image

image

注意一下,sharedId="MyApp"/ 兩個應用程式都使用相同的 sharedId。如果不同,就是不同的 session 了.

結論

使用 Windows Server AppFabric 的 Cache 作為 ASP.NET 的 Session,除了享有高可用性(High Avaliability)外,也意外地擁有跟應用程式共用 Session 的效果。

但,這樣好處的前提是:需要同一個Session。如果使用打開兩次 Internet Explorer,甚至不同的 browser,就很容易看不到同一個 session 了。

範例程式下載

沒有留言:

Share with Facebook