|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
|
[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 在处理客户端请求时,首先将根据客户端环境,生成一个 System.Web.HttpContext 对象,并将此对象作为执行上下文传递给后面的页面执行代码。 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 方法初始化。 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>
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|
|
|
|
|