分享
 
 
 

ASP.NETSession实现会话的建立流程

王朝asp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

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"

);

}

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"

);

}

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 一节的配置信息进行初始化的。

以下内容为程序代码:

httpModules 节点指定了 HttpApplication 需要初始化的模块列表,而在前面提到的 HttpApplication.InitModules 函数正式根据此列表进行初始化的以下内容为程序代码:private void HttpApplication.InitModules(){HttpModulesConfiguration cfgModules = ((HttpModulesConfiguration) HttpContext.GetAppConfig("system.web/httpModules"

);if (cfgModules == null){Thrownew HttpException(HttpRuntime.FormatResourceString("Missing_modules_config"
);}_moduleCollection = cfgModules.CreateModules();for(int i = 0; i{_moduleCollection[i].Init(this);}GlobalizationConfig cfgGlobal = ((GlobalizationConfig) HttpContext.GetAppConfig("system.web/globalization"
);if (cfgGlobal != null){_appLevelCulture = cfgGlobal.Culture;_appLevelUICulture = cfgGlobal.UICulture;}}Session 节点对于的 System.Web.SessionState.SessionStateModule 对象将被 HttpModulesConfiguration.CreateModules 方法构造,并调用其 Init 函数初始化。SessionStateModule 类实际上就是负责管理并创建会话,用户完全可以自行创建一个实现 IHttpModule 接口的类,实现会话的控制,如实现支持集群的状态同步等等。SessionStateModule.Init 方法主要负责 machine.config 文件中的 ses

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有