65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET 会话管理内部机制

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.52/5 (28投票s)

2004 年 8 月 3 日

4分钟阅读

viewsIcon

314712

本文将深入探讨 ASP.NET 会话管理内部机制。

Sample Image - HttpSessionState.jpg

引言

由于 HTTP 协议的无状态性,每个 ASP.NET 应用程序都需要管理客户端会话信息。在新闻组、论坛和邮件列表中经常被问到的一个问题是:ASP.NET 会话管理是如何工作的?在 Web 场或高并发用户的大型网站中,哪种 ASP.NET 技术是管理会话的最佳方式?我们将从快速概述 ASP.NET 会话管理选项开始,然后深入探讨 ASP.NET 会话管理内部机制,并在最后提出一些建议。

ASP.NET 会话管理选项

ASP.NET 提供了三种会话状态存储模式,由您的 Web 应用程序的 Web.config 文件中 <sessionState> 标签的 mode 属性控制。下面是该标签的一个示例:

<sessionState 
    mode="InProc"
    stateConnectionString="tcpip=127.0.0.1:42424"
    sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
    cookieless="false" 
    timeout="20" />
Attribute 选项 描述
模式   指定会话状态的存储位置。
  关闭 禁用会话状态管理。
  InProc 会话状态存储在 ASP.NET 工作进程的本地内存中。
  StateServer 会话状态存储在 ASP.NET 工作进程之外,由 Windows 服务管理。该服务的地址由 stateConnectionString 属性指定。
  SQLServer 会话状态存储在 ASP.NET 工作进程之外的 SQL Server 数据库中。该数据库的地址由 sqlConnectionString 属性表示。

现在,让我们看看会话存储的内部机制。

我们通过一个名为 Session 的属性来访问 Session 数据。这个 Session 属性由 System.Web.HttpContext 类和 System.Web.UI.Page 公开。(每个 ASP.NET 页面都会被转换为一个派生自 Page 类的类。)这个 Session 属性是 System.Web.SessionState 命名空间下的 HttpSessionState 类的一个对象,如上所示。

HttpSession 对象有一个名为 _dict 的私有成员,其类型为 SessionDictionary(命名空间 System.Web.SessionState),如下所示。

private SessionDictionary _dict;

SessionDictionary 是一个派生自 NameObjectCollectionBase 的内部类。

关系在一个小型类图中有所体现。

SessionDictionary relationship

会话状态管理中最重要的部分是一个名为 SessionStateModuleHttpModule。这个 HttpModule 与会话状态提供程序通信,并为每个 HTTP 请求填充 HttpSessionState。这个 HttpModule 在您的 machine.config 文件的 <httpModules> 部分列出。

为了参考,我从我的计算机的 machine.config 文件中复制了该部分的一部分。

<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule"/>
<add name="Session" type="System.Web.SessionState.SessionStateModule"/>
.
.
.
</httpModules>

对于您 ASP.NET 应用程序中的每个页面发起的 HTTP 请求,都会创建一个 HttpWorkerRequest 类型的对象,并由 HttpApplication 类的一个实例来处理。(有关 HTTP Pipeline 模型的完整讨论,请参阅“参考文献”中提到的 URL。)

在此请求处理过程中,会调用 HttpApplication 类的 InitModules() 方法。

下面的图 3 描绘了整个调用序列。

call graph

InitModules() 内部,所有在 <system.web>/<httpModules> 部分列出的模块都会被初始化,即每个 HttpModuleInit 方法都会被调用,也就是会调用 SessionStateModuleInit 方法。在 SessionStateModuleInit 方法中,会话状态设置从您的 ASP.NET 应用程序的 web.config 文件的 <system.web>/<sessionState> 部分读取,然后调用另一个方法 InitModuleFromConfig。该方法的签名如下所示。

private void InitModuleFromConfig(HttpApplication app, 
                                     Config config, bool configInit);

参数 app 代表正在用于处理 HTTP 请求的 HttpApplication 类的一个实例。

InitModuleFromConfigHttpApplicationInitInternal() 方法引发的与会话管理相关的事件添加各种事件处理程序。

下表显示了 SessionStateModule 中的哪些 EventHandlerHttpApplication 类的哪些事件相关联。

表:SessionStateModule 处理的 HttpApplication 事件 事件处理程序
事件 事件处理程序
AcquireRequestState BeginAcquireState, EndAcquireState
ReleaseRequestState OnReleaseState
EndRequest OnEndRequest

请注意,此时会话状态数据尚未获取。在上述 EventHandler 被绑定之后,还会发生另一件重要的事情。根据您的 ASP.NET 应用程序配置文件中 <system.web>/<sessionState> 部分的属性值设置,会话状态提供程序会绑定到 SessionStateModule

所有会话状态提供程序都实现了 IStateClientManager 接口。

下表显示了基于 sessionStateTagmode 属性值用于管理状态的对象类型。

<System.web>\<sessionState> 的模式属性基于的会话状态提供程序
模式 处理会话状态的类
InProc InProcStateClientManager
StateServer OutOfProcStateClientManager
SQLServer SqlStateClientManager

这个会话状态提供程序或 StateClientManager 存储在 SessionStateModule 的一个私有变量中。

一旦 SessionStateModuleInit() 方法将控制权交还给 HttpApplicationInitInternal 方法,处理就会继续,并引发 AcquireRequestState 事件。

此时会话状态才会被实际获取。当此事件被引发时,SessionStateModule 中先前绑定的事件处理程序(BeginAcquireState)会被调用,然后调用 SessionStateModuleGetSessionStateItem,后者会请求 StateClientManager 来获取会话状态。

为了判断性能差异,我们将逐一考察这些 StateClientManager,看看会话数据是如何实际存储和检索的。欲知更多详情,敬请期待第二部分。

参考文献

© . All rights reserved.