ASP.NET Session 实现会话的建立流程‖很重要的原因。而为了在无
务器端会话 (Session) 的
个客户端的会话;当客户端
交的某种凭据,如 Cookie
言和开发环境中大量得到应
获得如此大的成功,其设计实现
状态的 HTTP 请求和有状态的客
概念。客户端在连接到服务器后
通过无状态 HTTP 协议再次连接
或 URL 参数,将客户关联到某
用。
| 的简洁性和无状态连接的高效率是
户端操作之间达到平衡,产生了服
,就由 Web 服务器产生并维护一
到服务器时,服务器根据客户端提
个会话上。这种思路在各种开发语
| 在 ASP.NET 中,Web
HttpSessionState 分离 We
中实现,运行时编译成 Sys
System.Web.SessionState.
过 ASP.NET 页面编译成的
ASP.NET 中不同层次关系可
浅析 [1] 自动预编译机制
| 应用程序和会话状态被分别进行
b 应用程序与会话的功能。应用
tem.Web.HttpApplication 的实
HttpSessionState 实例,由服
System.Web.UI.Page 对象子类
参考我以前的一篇文章《.NET 1
浅析》,以下简称【文1】。
| 维护,通过 HttpApplication 和
程序层逻辑在 Global.asax 文件
例;会话则作为单独的
务器统一为每个用户会话维护,通
的 Session 属性访问。关于
.1中预编译ASP.NET页面实现原理
|
ASP.NET 在处理客户端
m.Web.HttpContext 对象,
| 请求时,首先将根据客户端环境
并将此对象作为执行上下文传递
| ,生成一个 Syste
给后面的页面执行代码。
|
在【文1】的分析中我们可以看到,H
HttpWorkerRequest 中给出的环境,构造
序池中获取可用应用程序。简要代码如下
| ttpRuntime 在处理页面请求之前,根据
HttpContext 对象,并以次对象作为参数从应用程
:
|
private void HttpRuntime.Process
| RequestInternal(HttpWorkerRequest wr)
|
HttpContext ctxt = n
| ew HttpContext(wr, 0);
|
IHttpHandler handler = HttpAppli
| cationFactory.GetApplicationInstance(ctxt);
|
HttpApplicationFacto
用程序对象构造的负荷。
| ry 工厂内部维护了一个可用的
| 应用程序实例缓冲池,用户降低应
|
如果池中没有可用的应
Web.HttpRuntime.CreateNo
InitInternal 方法初始化
| 用程序对象实例,此对象工厂最
nPublicInstance 方法构造新的
。详细步骤分析见【文1】
| 终会调用 System.
应用程序实例,并调用其
|
internal static IHtt
onInstance(HttpContext c
| pHandler HttpApplicationFact
txt)
| ory.GetApplicati
|
// 判断是否需要初始化当前 HttpAp
| plicationFactory 实例
|
return HttpApplicationFactory._t
NormalApplicationInstance(ctxt);
| heApplicationFactory.Get
|
private HttpApplicat
ionInstance(HttpContext
| ion HttpApplicationFactory.G
context)
| etNormalApplicat
|
| HttpApplication app = null; |
| // 尝试从已施放的 Web 应用程序实例队列中获取 |
app = (HttpApplicati
tance(this._theApplicati
| on)System.Web.HttpRuntime.Cr
onType);
| eateNonPublicIns
|
app.InitInternal(context, this._
| state, this._eventHandlerMethods);
|
这里的 System.Web.Ht
工作,包括调用 HttpAppli
,并将作为参数传入的 Htt
HTTP 上下文对象将被后面
| tpApplication.InitInternal
cation.InitModules 函数初始
pContext 实例保存到 HttpAppl
用于获取会话对象。
| 函数完成对应用程序对象的初始化
化 HTTP 模块(后面将详细介绍)
ication._context 字段中。而此
|
| public class HttpApplication : ... |
| private HttpContext _context; |
| private HttpSessionState _session; |
| public HttpSessionState Session |
| HttpSessionState state = null; |
| if (this._session != null) |
| else if (this._context != null) |
| state = this._context.Session; |
Throw new HttpExcep
on_not_available"[img]/i
| tion(HttpRuntime.FormatResou
mages/wink.gif[/img]);
| rceString("Sessi
|
而在 ASP.NET 页面中获取会话的方
| 法也是类似,都是通过 HttpContext 来完成的。
|
| private HttpSessionState _session; |
| private bool _sessionRetrieved; |
| public virtual HttpSessionState Session |
| if (!this._sessionRetrieved) |
| this._sessionRetrieved = true; |
| this._session = this.Context.Session; |
| if (this._session == null) |
Throw new HttpExcep
on_not_enabled"[img]/ima
| tion(HttpRuntime.FormatResou
ges/wink.gif[/img]);
| rceString("Sessi
|
在 HttpContext 中,实际上是通过
| 一个哈希表保存诸如会话对象之类信息的
|
| public sealed class HttpContext : ... |
| private Hashtable _items; |
| this._items = new Hashtable(); |
| public HttpSessionState Session |
return ((HttpSession
| State) this.Items["AspSessio
| n"]);
|
而 HttpContext.Sessi
HttpApplication.InitModu
| on 所访问的又是哪儿来的呢?
les 函数。
| 这就又需要回到我们前面提及的
|
在 .NET 安装目录 Config 子目录下
HttpApplication 就是使用其中 system.
| 的 machine.config 定义了全局性的配置信息,而
web 一节的配置信息进行初始化的。
|
httpModules 节点指定
HttpApplication.InitModu
| 了 HttpApplication 需要初始
les 函数正式根据此列表进行初
| 化的模块列表,而在前面提到的
始化的
|
private void HttpApplication.Ini
| tModules()
|
HttpModulesConfiguration cfgModu
HttpContext.GetAppConfig("system.web
| les = ((HttpModulesConfiguration)
/httpModules"[img]/images/wink.gif[/img]);
|
Throw new HttpExcep
ng_modules_config"[img]/
| tion(HttpRuntime.FormatResou
images/wink.gif[/img]);
| rceString("Missi
|
_moduleCollection =
| cfgModules.CreateModules();
|
| for(int i = 0; i < _moduleCollection.Count; i++) |
| _moduleCollection[i].Init(this); |
GlobalizationConfig cfgGlobal =
ttpContext.GetAppConfig("system.web/
| ((GlobalizationConfig) H
globalization"[img]/images/wink.gif[/img]);
|
| _appLevelCulture = cfgGlobal.Culture; |
_appLevelUICulture = cfgGlobal.U
| ICulture;
|
Session 节点对于的 S
HttpModulesConfiguration
SessionStateModule 类实
IHttpModule 接口的类,实
| ystem.Web.SessionState.Sessi
.CreateModules 方法构造,并
际上就是负责管理并创建会话,
现会话的控制,如实现支持集群
| onStateModule 对象将被
调用其 Init 函数初始化。
用户完全可以自行创建一个实现
的状态同步等等。
|
SessionStateModule.I
,调用 SessionStateModul
| nit 方法主要负责 machine.con
e.InitModuleFromConfig 方法
| fig 文件中的 sessionState 配置
建立相应的会话管理器。
|
stateConnectionStrin
| g="tcpip=127.0.0.1:42424"
|
sqlConnectionString=
| "data source=127.0.0.1;Integ
| rated Security=SSPI"
|
sessionState 的使用
Management Overview。关
的建立过程。
| 方法请参加 MSDN 中相关介绍和
于不同 mode 的会话管理的话题
| INFO: ASP.NET State
我们后面再讨论,先继续来看会话
|
在从 machine.config 文件中读取配
HttpApplication 实例注册几个会话管理
话状态。
| 置信息后,InitModuleFromConfig 方法会向
事件处理函数,负责在应用程序合适的情况下维护会
|
private void Session
| StateModule.InitModuleFromCo
| nfig(HttpApplication app,
|
SessionStateSectionH
| andler.Config config, bool c
| onfigInit)
|
app.AddOnAcquireRequestStateAsyn
this.BeginAcquireState),
| c(new BeginEventHandler(
|
new EndEventHandler(
| this.EndAcquireState));
|
app.ReleaseRequestState += new E
| ventHandler(this.OnReleaseState);
|
app.EndRequest += ne
| w EventHandler(this.OnEndReq
| uest);
|
BeginAcquireState 和
ttpApplication._acquireR
在合适的时候清理会话状态
杂的请求结束处理。前面提
后,会将上述这些事件处理
线机制进行调用,最大化处
HTTP PIPELINES
| EndAcquireState 作为一个异
equestStateEventHandlerAsync
;OnEndRequest 则是 OnReleas
到的 HttpApplication.InitInt
器,加入到一个执行队列中,由
理效率。有关 ASP.NET 中流水
| 步处理器注册到 H
字段上;OnReleaseState 则负责
eState 的一个包装,负责较为复
ernal 函数,在完成了初始化工作
应用程序在合适的时候,使用流水
线事件模型的相关介绍,请参考
|
Securely Implement Request Proce
with HTTP Pipelines in ASP.NET 一文
文章详细分析。
| ssing, Filtering, and Content Redirection
中 The Pipeline Event Model 小节,有机会我在写
|
知道了会话建立的调用
teModule.BeginAcquireSta
复杂情况后,使用 Session
作,并将封装会话的 HttpS
的哈希表中,也就是前面提
StateModule.OnReleaseSta
HttpSessionState 对象,
| 流程再来看会话的实现就比较简
te 被 HttpApplication 实例在
StateModule.CompleteAcquireS
essionState 对象以 "AspSessi
到的 HttpContext.Context 的
te 则从 HttpContext 中删除 "
并对会话管理器进行同步工作。
| 单了,SessionSta
合适的时候调用,处理各种会话的
tate 函数完成实际的会话建立工
on" 为 key 加入到 HttpContext
由来。而 Session
AspSession" 为 key 的
|
至此,ASP.NET 中的会话建立流程大
同会话管理器的实现原理与应用
| 概就分析完毕了,下一小节将进一步展开分析多种不
|
上一页> 下一页>