六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

ASP.NET 中 Session 完成原理淺析 [1] 會話的創建流程

[摘要]HTTP 協議之所以能夠獲得如此大的成功,其設計實現的簡潔性和無狀態連接的高效率是很重要的原因。而為了在無狀態的 HTTP 請求和有狀態的客戶端操作之間達到平衡,產生了服務器端會話 (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"[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...




主站蜘蛛池模板: 污污免费视频 | 日韩a级片 | 亚洲第成色999久久网站 | 日本免费中文字幕在线看 | 一级一级 a爱片免费视频 | 日本特黄a级高清免费酷网 日本特黄aaaaaaa大片 | 手机看片自拍自拍自拍自视频 | 亚洲欧美精品一区二区 | 青青青手机在线观看 | 午夜视频播放 | 日韩欧美无线在码 | 中文字幕乱码一二三四区 | 夜夜夜网站 | 天天骑天天干 | 亚洲欧美国产精品专区久久 | 涩涩涩涩涩涩涩 | 性欧美大战久久久久久久久 | 日韩第3页 | 色综合中文字幕 | 人人艹人人射 | 影音先锋国产系列精品 | 青草全福视在线 | 中文字幕在线视频免费观看 | 日本高清视频免费看 | 在线欧美自拍 | 亚洲激情视频在线播放 | 中文字幕伦伦在线中文字 | 手机国产乱子伦精品视频 | 欧美在线视频播放 | 亚洲男人的天堂久久香蕉 | 亚洲最新网址 | 啪啪免费视频 | 四虎免费永久观看 | 亚洲乱码在线视频 | 日韩中文有码高清 | 日本在线日本中文字幕日本在线视频播放 | 四虎国产精品免费久久影院 | 三十极夜2免费视频 | 亚洲第五页 | 日本一区二区三区在线 观看网站 | 一级片久久 |