分类

  • 软件天地

  • 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)
      {                                                                            
      // 构造 HTTP 调用上下文对象                                          

      HttpContext ctxt = n
    ew HttpContext(wr, 0);

      //...                                                                    

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

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

      HttpApplicationFacto
    用程序对象构造的负荷。
    ry 工厂内部维护了一个可用的

    应用程序实例缓冲池,用户降低应

      如果池中没有可用的应
    Web.HttpRuntime.CreateNo
    InitInternal 方法初始化
    用程序对象实例,此对象工厂最
    nPublicInstance 方法构造新的
    。详细步骤分析见【文1】
    终会调用 System.
    应用程序实例,并调用其

      以下内容为程序代码:                                                          

      internal static IHtt
    onInstance(HttpContext c
    pHandler HttpApplicationFact
    txt)
    ory.GetApplicati

      {                                                                            
      // 处理定制应用程序                                                        
      //...                                                                    

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

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

      // 获取 Web 应用程序实例                                              
      return HttpApplicationFactory._t
    NormalApplicationInstance(ctxt);
    heApplicationFactory.Get

      }                                                                            

      private HttpApplicat
    ionInstance(HttpContext
    ion HttpApplicationFactory.G
    context)
    etNormalApplicat

      {                                                                            
      HttpApplication app = null;                        

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

      if(app == null)                                                
      {                                                                            
      // 构造新的 Web 应用程序实例                                          
      app = (HttpApplicati
    tance(this._theApplicati
    on)System.Web.HttpRuntime.Cr
    onType);
    eateNonPublicIns


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

      return app;                                                        
      }                                                                            

      这里的 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                
      {                                                                            
      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 HttpExcep
    on_not_available"[img]/i
    tion(HttpRuntime.FormatResou
    mages/wink.gif[/img]);
    rceString("Sessi

      }                                                                            
      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 HttpExcep
    on_not_enabled"[img]/ima
    tion(HttpRuntime.FormatResou
    ges/wink.gif[/img]);
    rceString("Sessi

      }                                                                            
      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 ((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]);

      if (cfgModules == null)                                
      {                                                                            
      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]);
      if (cfgGlobal != null)                                  
      {                                                                            
      _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"
      stateNetworkTimeout="10"                              
      sqlConnectionString=
    "data source=127.0.0.1;Integ
    rated Security=SSPI"
      cookieless="false"                                          
      timeout="20" />

      


      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)
      {                                                                            
      // 处理不使用 Cookie 的情况                                        
      //...                                                                    

      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 中的会话建立流程大
    同会话管理器的实现原理与应用
    概就分析完毕了,下一小节将进一步展开分析多种不



    上一页 下一页




    map