首页 电脑学院 黑客教程 网站技术 网页特效 免费论文 公文写作 演讲发言 实用文档 职场指南 时尚生活 情感男女 其他资讯

您的位置:首页-> 网站技术-> .NET技术-> ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程
ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程
HTTP 协议之所以能够获得如此大的成功,其设计实现的简洁性和无状态连接的高效率是很重要的原因。而为了在无状态的 HTTP 请求和有状态的客户端操作之间达到平衡,产生了服务器端会话 (Session) 的概念。客户端在连接到服务器后,就由 Web 服务器产生并维护一个客户端的会话;当客户端通过无状态 HTTP 协议再次连接到服务器时,服务器根据客户端提交的某种凭据,如 Cookie 或 URL 参数,将客户关联到某个会话上。这种思路在各种开发语言和开发环境中大量得到应用。
在 ASP.NET 中,Web 应用程序和会话状态被分别进行维护,通过 HttpApplication 和 HttpSessionState 分离 Web 应用程序与会话的功能。应用程序层逻辑在 Global.asax 文件中实现,运行时编译成 System.Web.HttpApplication 的实例;会话则作为单独的 System.Web.SessionState.HttpSessionState 实例,由服务器统一为每个用户会话维护,通过 ASP.NET 页面编译成的 System.Web.UI.Page 对象子类的 Session 属性访问。关于 ASP.NET 中不同层次关系可参考我以前的一篇文章《.NET 1.1中预编译ASP.NET页面实现原理浅析 [1] 自动预编译机制浅析》,以下简称【文1】。

ASP.NET 在处理客户端请求时,首先将根据客户端环境,生成一个 System.Web.HttpContext 对象,并将此对象作为执行上下文传递给后面的页面执行代码。
在【文1】的分析中我们可以看到,HttpRuntime 在处理页面请求之前,根据 HttpWorkerRequest 中给出的环境,构造 HttpContext 对象,并以次对象作为参数从应用程序池中获取可用应用程序。简要代码如下:
以下内容为程序代码:

private void HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)
{
// 构造 HTTP 调用上下文对象
HttpContext ctxt = new HttpContext(wr, 0);

//...

// 获取当前 Web 应用程序实例
IHttpHandler handler = HttpApplicationFactory.GetApplicationInstance(ctxt);

// 调用 handler 实际处理页面请求
}




HttpApplicationFactory 工厂内部维护了一个可用的应用程序实例缓冲池,用户降低应用程序对象构造的负荷。
如果池中没有可用的应用程序对象实例,此对象工厂最终会调用 System.Web.HttpRuntime.CreateNonPublicInstance 方法构造新的应用程序实例,并调用其 InitInternal 方法初始化。详细步骤分析见【文1】
以下内容为程序代码:

internal static IHttpHandler HttpApplicationFactory.GetApplicationInstance(HttpContext ctxt)
{
// 处理定制应用程序
//...

// 处理调试请求
//...

// 判断是否需要初始化当前 HttpApplicationFactory 实例
//...

// 获取 Web 应用程序实例
return HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(ctxt);
}

private HttpApplication HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context)
{
HttpApplication app = null;

// 尝试从已施放的 Web 应用程序实例队列中获取
//...

if(app == null)
{
// 构造新的 Web 应用程序实例
app = (HttpApplication)System.Web.HttpRuntime.CreateNonPublicInstance(this._theApplicationType);

// 初始化 Web 应用程序实例
app.InitInternal(context, this._state, this._eventHandlerMethods);
}

return app;
}



这里的 System.Web.HttpApplication.InitInternal 函数完成对应用程序对象的初始化工作,包括调用 HttpApplication.InitModules 函数初始化 HTTP 模块(后面将详细介绍),并将作为参数传入的 HttpContext 实例保存到 HttpApplication._context 字段中。而此 HTTP 上下文对象将被后面用于获取会话对象。
以下内容为程序代码:

public class HttpApplication : ...
{
private HttpContext _context;
private HttpSessionState _session;

public HttpSessionState Session
{
get
{
HttpSessionState state = null;
if (this._session != null)
{
state = this._session;
}
else if (this._context != null)
{
state = this._context.Session;
}
if (state == null)
{
throw new HttpException(HttpRuntime.FormatResourceString("Session_not_available"[img]/images/wink.gif[/img]);
}
return state;
}
}
}



而在 ASP.NET 页面中获取会话的方法也是类似,都是通过 HttpContext 来完成的。
以下内容为程序代码:

public class Page : ...
{
private HttpSessionState _session;
private bool _sessionRetrieved;

public virtual HttpSessionState Session
{
get
{
if (!this._sessionRetrieved)
{
this._sessionRetrieved = true;
try
{
this._session = this.Context.Session;
}
catch (Exception)
{
}
}
if (this._session == null)
{
throw new HttpException(HttpRuntime.FormatResourceString("Session_not_enabled"[img]/images/wink.gif[/img]);
}
return this._session;
}
}
}



在 HttpContext 中,实际上是通过一个哈希表保存诸如会话对象之类信息的
以下内容为程序代码:

public sealed class HttpContext : ...
{
private Hashtable _items;

public IDictionary Items
{
get
{
if (this._items == null)
{
this._items = new Hashtable();
}
return this._items;
}
}

public HttpSessionState Session
{
get
{
return ((HttpSessionState) this.Items["AspSession"]);
}
}
}



而 HttpContext.Session 所访问的又是哪儿来的呢?这就又需要回到我们前面提及的 HttpApplication.InitModules 函数。

在 .NET 安装目录 Config 子目录下的 machine.config 定义了全局性的配置信息,而 HttpApplication 就是使用其中 system.web 一节的配置信息进行初始化的。
以下内容为程序代码:

<system.web>
<httpModules>
<add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
<add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
<add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
<add name="PassportAuthentication" type="System.Web.Security.PassportAuthenticationModule" />
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
<add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />
<add name="ErrorHandlerModule" type="System.Web.Mobile.ErrorHandlerModule, System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</httpModules>
</system.web>



httpModules 节点指定了 HttpApplication 需要初始化的模块列表,而在前面提到的 HttpApplication.InitModules 函数正式根据此列表进行初始化的
以下内容为程序代码:

private void HttpApplication.InitModules()
{
HttpModulesConfiguration cfgModules = ((HttpModulesConfiguration) HttpContext.GetAppConfig("system.web/httpModules"[img]/images/wink.gif[/img]);

if (cfgModules == null)
{
throw new HttpException(HttpRuntime.FormatResourceString("Missing_modules_config"[img]/images/wink.gif[/img]);
}
_moduleCollection = cfgModules.CreateModules();

for(int i = 0; i < _moduleCollection.Count; i++)
{
_moduleCollection[i].Init(this);
}

GlobalizationConfig cfgGlobal = ((GlobalizationConfig) HttpContext.GetAppConfig("system.web/globalization"[img]/images/wink.gif[/img]);
if (cfgGlobal != null)
{
_appLevelCulture = cfgGlobal.Culture;
_appLevelUICulture = cfgGlobal.UICulture;
}
}



Session 节点对于的 System.Web.SessionState.SessionStateModule 对象将被 HttpModulesConfiguration.CreateModules 方法构造,并调用其 Init 函数初始化。SessionStateModule 类实际上就是负责管理并创建会话,用户完全可以自行创建一个实现 IHttpModule 接口的类,实现会话的控制,如实现支持集群的状态同步等等。
SessionStateModule.Init 方法主要负责 machine.config 文件中的 sessionState 配置,调用 SessionStateModule.InitModuleFromConfig 方法建立相应的会话管理器。
以下内容为程序代码:

<system.web>
<sessionState mode="InProc"
stateConnectionString="tcpip=127.0.0.1:42424"
stateNetworkTimeout="10"
sqlConnectionString="data source=127.0.0.1;Integrated Security=SSPI"
cookieless="false"
timeout="20" />
</system.web>



sessionState 的使用方法请参加 MSDN 中相关介绍和 INFO: ASP.NET State Management Overview。关于不同 mode 的会话管理的话题我们后面再讨论,先继续来看会话的建立过程。

在从 machine.config 文件中读取配置信息后,InitModuleFromConfig 方法会向 HttpApplication 实例注册几个会话管理事件处理函数,负责在应用程序合适的情况下维护会话状态。
以下内容为程序代码:

private void SessionStateModule.InitModuleFromConfig(HttpApplication app,
SessionStateSectionHandler.Config config, bool configInit)
{
// 处理不使用 Cookie 的情况
//...

app.AddOnAcquireRequestStateAsync(new BeginEventHandler(this.BeginAcquireState),
new EndEventHandler(this.EndAcquireState));
app.ReleaseRequestState += new EventHandler(this.OnReleaseState);
app.EndRequest += new EventHandler(this.OnEndRequest);

// 创建会话管理器
//...
}



BeginAcquireState 和 EndAcquireState 作为一个异步处理器注册到 HttpApplication._acquireRequestStateEventHandlerAsync 字段上;OnReleaseState 则负责在合适的时候清理会话状态;OnEndRequest 则是 OnReleaseState 的一个包装,负责较为复杂的请求结束处理。前面提到的 HttpApplication.InitInternal 函数,在完成了初始化工作后,会将上述这些事件处理器,加入到一个执行队列中,由应用程序在合适的时候,使用流水线机制进行调用,最大化处理效率。有关 ASP.NET 中流水线事件模型的相关介绍,请参考 HTTP PIPELINES
Securely Implement Request Processing, Filtering, and Content Redirection with HTTP Pipelines in ASP.NET 一文中 The Pipeline Event Model 小节,有机会我在写文章详细分析。

知道了会话建立的调用流程再来看会话的实现就比较简单了,SessionStateModule.BeginAcquireState 被 HttpApplication 实例在合适的时候调用,处理各种会话的复杂情况后,使用 SessionStateModule.CompleteAcquireState 函数完成实际的会话建立工作,并将封装会话的 HttpSessionState 对象以 "AspSession" 为 key 加入到 HttpContext 的哈希表中,也就是前面提到的 HttpContext.Context 的由来。而 SessionStateModule.OnReleaseState 则从 HttpContext 中删除 "AspSession" 为 key 的 HttpSessionState 对象,并对会话管理器进行同步工作。

至此,ASP.NET 中的会话建立流程大概就分析完毕了,下一小节将进一步展开分析多种不同会话管理器的实现原理与应用。

to be continue...



在百度中查找更多ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程的内容
职场宝典   职场故事   职场跳槽   职场文化   职场理财   职场充电   情感天地   职场女性   职场礼仪   职场新人
报告总结   述职报告 工作总结 调查报告 工作汇报 计划方案 个人总结 社会实践 规章制度 调研报告 
  实习报告 考察报告 辞职报告 
演讲发言   竞职演说   就职演说   精彩演说   爱国演讲   英语演讲   十七大演讲   安全生产演讲稿   
节日祝福   重阳节 国庆节 教师节 中秋节 情人节 七夕节 劳动节 妇女节 清明节 愚人节 春节 元旦 圣诞节  儿童节  端午节 母亲节 新婚祝福 生日祝福 
讲话致辞   开业开幕   会议主持   庆典致辞   会议发言   党风廉政   党政报告   贺电慰问   婚丧嫁娶   思想宣传
法律常识   基本常识   法律文书   权益常识   劳动保障   婚姻继承   民事诉讼   刑事诉讼   
党建材料   入党申请   思想学习   党性分析   思想汇报   转正申请   民主生活   党委党建   入团申请   申报材料
求职简历   个人简历   求职自荐   求职谋略   面试技巧   求职英语   自我鉴定   英文简历   简历封面
心得体会   心得体会   经验交流   读后感   
时政热点   和谐社会   先进性教育   新农村建设   十七大   八荣八耻   科学发展观   劳动合同法   
人际沟通   社交技巧   社交礼仪   口才技巧   谈话技巧   演讲技巧   
营销技巧   电话销售   网络销售   推销技巧   促销技巧   销售口才   营销手段   销售技巧   谈判技巧   

“ ASP.NET 中 Session 实现原理浅析 [1] 会话的建立流程”来源于网络,版权归作者所有!勿用于商业用途。

.NET技术

ASP技术
PHP技术
JSP技术
.NET技术
服务器技术
数据库开发
其它类

本类阅读TOP10

·数据库的连接串(中文)
·DES(Data Encryption Standard)加密解密整理
·利用Jmail发送和接收邮件(C#)
·.NET Framework 中多语言支持的实现
·动态菜单
·.NET 框架类库(上)
·C#中的事件
·微软.NET战略和ASP.NET简介(1)
·加密与解密
·ASP.NET中的代码分离

广告


关于本站|服务条款|广告服务|客服中心|发布文章|网站留言