ASP.NET Session 實現會話的建立流程

來源:互聯網
上載者:User
asp.net|session

  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 一節的配置資訊進行初始化的。
  以下內容為程式碼:
  
  <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");
  
  if (cfgModules == null)
  {
  Throw new HttpException(HttpRuntime.FormatResourceString("Missing_modules_config");
  }
  _moduleCollection = cfgModules.CreateModules();
  
  for(int i = 0; i < _moduleCollection.Count; 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



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.