溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

發(fā)布時(shí)間:2021-10-29 17:00:52 來(lái)源:億速云 閱讀:120 作者:柒染 欄目:編程語(yǔ)言

這篇文章給大家介紹如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

前言

前一段在整理郵件的時(shí)候發(fā)現(xiàn)幾年前和CDD老師交流時(shí)的一份郵件.下面是簡(jiǎn)單摘要:

“從技術(shù)角度來(lái)說(shuō),無(wú)論哪一個(gè)陣營(yíng),跟新技術(shù)都是不可避免的,也是很累的,當(dāng)然作為一個(gè)程序員來(lái)說(shuō),也是必須的。要想讓技術(shù)的更新對(duì)自己的影響減小,基礎(chǔ)就必須打牢。所以,底層的東西和抽象層的東西需要下一番功夫。因?yàn)檎f(shuō)到底,無(wú)論什么技術(shù),無(wú)非就是架構(gòu)和最終的實(shí)現(xiàn),技術(shù)框架只是應(yīng)用開(kāi)發(fā)的一個(gè)平臺(tái)一種技術(shù),如果了解了具體的東西,技術(shù)更新對(duì)你來(lái)說(shuō)就沒(méi)什么影響了,或者換句話(huà)說(shuō),你要學(xué)一種新的技術(shù),速度和效率會(huì)非常之高?!?/p>

上面一段話(huà)對(duì)自己的影響很大,可能大家在踏入“程序人生”的時(shí)候都會(huì)存在一些迷茫和彷徨。盡管我是屬于那種相當(dāng)熱愛(ài)Proramming的一份子,但是面對(duì)萬(wàn)花筒般的技術(shù)分支也曾徘徊猶豫過(guò).徘徊之余要做的事情便是夯實(shí)基礎(chǔ),尋找自己的興趣與方向.對(duì)技術(shù)的迭代,以不變應(yīng)萬(wàn)變才是王道.

正因?yàn)槿绱?所以也不會(huì)存在銀彈之說(shuō).如果真的有銀彈的話(huà)那么我信奉的是:程序=數(shù)據(jù)結(jié)構(gòu)+算法

我選擇的方向是Web,也相信Web終究會(huì)是互聯(lián)網(wǎng)的未來(lái).這篇文章簡(jiǎn)單談一下自己對(duì).NET平臺(tái)下Web基礎(chǔ)的一些淺解,由于自己水平有限,不足之處煩請(qǐng)見(jiàn)諒.

HTTP協(xié)議

HTTP協(xié)議是瀏覽器和服務(wù)器雙方共同遵循的規(guī)范.是一種基于TCP/IP(傳輸層協(xié)議,相對(duì)應(yīng)的有UDP)的"應(yīng)用層協(xié)議"

PS:TCP/UDP是廣泛使用的網(wǎng)絡(luò)通信協(xié)議,UDP協(xié)議具有不可靠性和不安全性,

相對(duì)來(lái)說(shuō)TCP協(xié)議是基于連接和三次握手的(相對(duì)可靠與安全),然而B(niǎo)/S架構(gòu)的網(wǎng)站,由于同時(shí)在線(xiàn)的人數(shù)會(huì)很多,如果都與服務(wù)器保持連接狀態(tài).服務(wù)器的承載是相當(dāng)大的,

因而衍生出HTTP協(xié)議.簡(jiǎn)單的說(shuō):請(qǐng)求發(fā)起之后服務(wù)器端立刻關(guān)閉連接并釋放資源.也正因?yàn)槿绱?HTTP協(xié)議通常被理解為”無(wú)狀態(tài)”的.

當(dāng)然維系"狀態(tài)"的手段有很多;如 Session/Cookie等 這里暫且不多做討論.

先來(lái)看一下典型的OSI七層模型 圖解

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

HTTP最通俗的理解 請(qǐng)求/響應(yīng).

圖示:

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

HTTP報(bào)文信息

HTTP Request Header

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

HTTP Response Header

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

當(dāng)然,也可以通過(guò)設(shè)置改變?yōu)g覽器的選項(xiàng).這里不做詳細(xì)說(shuō)明.不清楚的可以Google.如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

給出ASP.NET下添加P3P頭信息的例子

HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");

有興趣詳細(xì)了解的可以參考 MSDN 中關(guān)于部署 P3P的文章。

下面是老生常談的內(nèi)容了(熟悉的朋友,自行跳過(guò),權(quán)當(dāng)溫習(xí)下了 : )   )

請(qǐng)求頭(消息頭)包含(客戶(hù)機(jī)請(qǐng)求的服務(wù)器主機(jī)名,客戶(hù)機(jī)的環(huán)境信息等):

Accept:用于告訴服務(wù)器,客戶(hù)機(jī)支持的數(shù)據(jù)類(lèi)型  (例如:Accept:text/html,image/*)

Accept-Charset:用于告訴服務(wù)器,客戶(hù)機(jī)采用的編碼格式

Accept-Encoding:用于告訴服務(wù)器,客戶(hù)機(jī)支持的數(shù)據(jù)壓縮格式

Accept-Language:客戶(hù)機(jī)語(yǔ)言環(huán)境

Host:客戶(hù)機(jī)通過(guò)這個(gè)服務(wù)器,想訪(fǎng)問(wèn)的主機(jī)名

If-Modified-Since:客戶(hù)機(jī)通過(guò)這個(gè)頭告訴服務(wù)器,資源的緩存時(shí)間

Referer:客戶(hù)機(jī)通過(guò)這個(gè)頭告訴服務(wù)器,它(客戶(hù)端)是從哪個(gè)資源來(lái)訪(fǎng)問(wèn)服務(wù)器的(防盜鏈)

User-Agent:客戶(hù)機(jī)通過(guò)這個(gè)頭告訴服務(wù)器,客戶(hù)機(jī)的軟件環(huán)境(操作系統(tǒng),瀏覽器版本等)

Cookie:客戶(hù)機(jī)通過(guò)這個(gè)頭,將Coockie信息帶給服務(wù)器

Connection:告訴服務(wù)器,請(qǐng)求完成后,是否保持連接

Date:告訴服務(wù)器,當(dāng)前請(qǐng)求的時(shí)間

一個(gè)http響應(yīng)代表服務(wù)器端向客戶(hù)端回送的數(shù)據(jù),它包括:

一個(gè)狀態(tài)行,若干個(gè)響應(yīng)消息頭,以及實(shí)體內(nèi)容

狀態(tài)行:  例如:  HTTP/1.1  200 OK   (協(xié)議的版本號(hào)是1.1  響應(yīng)狀態(tài)碼為200  響應(yīng)結(jié)果為 OK)

響應(yīng)頭(消息頭)包含:

Location:這個(gè)頭配合302狀態(tài)嗎,用于告訴客戶(hù)端找誰(shuí)

Server:服務(wù)器通過(guò)這個(gè)頭,告訴瀏覽器服務(wù)器的類(lèi)型

Content-Encoding:告訴瀏覽器,服務(wù)器的數(shù)據(jù)壓縮格式

Content-Length:告訴瀏覽器,回送數(shù)據(jù)的長(zhǎng)度

Content-Type:告訴瀏覽器,回送數(shù)據(jù)的類(lèi)型

Last-Modified:告訴瀏覽器當(dāng)前資源緩存時(shí)間

Refresh:告訴瀏覽器,隔多長(zhǎng)時(shí)間刷新

Content- Disposition:告訴瀏覽器以下載的方式打開(kāi)數(shù)據(jù)。例如: context.Response.AddHeader("Content-Disposition","attachment:filename=icon.jpg");                                        context.Response.WriteFile("icon.jpg");

Transfer-Encoding:告訴瀏覽器,傳送數(shù)據(jù)的編碼格式

ETag:緩存相關(guān)的頭(可以做到實(shí)時(shí)更新)

Expries:告訴瀏覽器回送的資源緩存多長(zhǎng)時(shí)間。如果是-1或者0,表示不緩存

Cache-Control:控制瀏覽器不要緩存數(shù)據(jù)   no-cache

Pragma:控制瀏覽器不要緩存數(shù)據(jù)          no-cache

Connection:響應(yīng)完成后,是否斷開(kāi)連接。  close/Keep-Alive

Date:告訴瀏覽器,服務(wù)器響應(yīng)時(shí)間

IIS運(yùn)行過(guò)程

有了上面的HTTP協(xié)議的知識(shí)回顧,下面來(lái)讓我們看下IIS是怎樣工作的?

IIS 5.X 已經(jīng)距離我們很遠(yuǎn)了.好吧 XP默認(rèn)的好像是的… 為萬(wàn)惡的IE6 默哀下0.0  .

這里我們來(lái)看一下IIS 6 的圖示

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

根據(jù)上圖簡(jiǎn)單分析下IIS6的運(yùn)行過(guò)程

在 User Mode 下,http.sys 接收到 http request,然后它會(huì)根據(jù) IIS 中的 Metabase 查看基于該 Request 的 Application 屬于哪個(gè) Application Pool, 如果該 Application Pool 不存在,則創(chuàng)建之。否則直接將 request 發(fā)到對(duì)應(yīng) Application Pool 的 Queue中。

每個(gè) Application Pool 對(duì)應(yīng)著一個(gè) Worker Process — w3wp.exe,(運(yùn)行在 User Mode 下)。在 IIS Metabase 中維護(hù)著 Application Pool 和 Worker Process 的Mapping。WAS(Web Administrative Service)根據(jù)這樣一個(gè) mapping,將存在于某個(gè) Application Pool Queue 的 request 傳遞到對(duì)應(yīng)的 Worker Process (如果沒(méi)有,就創(chuàng)建這樣一個(gè)進(jìn)程)。在 Worker Process 初始化的時(shí)候,加載 ASP.NET ISAPI,ASP.NET ISAPI 進(jìn)而加載 CLR。最后通過(guò) AppManagerAppDomainFactory 的 Create 方法為 Application 創(chuàng)建一個(gè) Application Domain;通過(guò) ISAPIRuntime 的  ProcessRequest 處理 Request,進(jìn)而將流程進(jìn)入到 ASP.NET Http Runtime Pipeline。

PS幾個(gè)知識(shí)點(diǎn):

  1. HTTP.SYS:(Kernel)的一個(gè)組件,它負(fù)責(zé)偵聽(tīng)(Listen)來(lái)自于外部的HTTP請(qǐng)求,根據(jù)請(qǐng)求的URL將其轉(zhuǎn)發(fā)給相應(yīng)的應(yīng)用程序池 (Application Pool)。當(dāng)此HTTP請(qǐng)求處理完成時(shí),它又負(fù)責(zé)將處理結(jié)果發(fā)送出去.為了提供更好的性能,HTTP.SYS內(nèi)部建立了一個(gè)緩沖區(qū),將最近的HTTP請(qǐng)求處理結(jié)果保存起來(lái)。

  2. Application Pool:  IIS總會(huì)保持一個(gè)單獨(dú)的工作進(jìn)程:應(yīng)用程序池。所有的處理都發(fā)生在這個(gè)進(jìn)程里,包括ISAPI dll的執(zhí)行。對(duì)于IIS6而言,應(yīng)用程序池是一個(gè)重大的改進(jìn),因?yàn)樗鼈冊(cè)试S以更小的粒度控制一個(gè)指定進(jìn)程的執(zhí)行。你可以為每一個(gè)虛擬目錄或者整個(gè)Web 站點(diǎn)配置應(yīng)用程序池,這可以使你很容易的把每一個(gè)應(yīng)用程序隔離到各自的進(jìn)程里,這樣就可以把它與運(yùn)行在同一臺(tái)機(jī)器上其他程序完全隔離。從Web處理的角度看,如果一個(gè)進(jìn)程死掉,至少它不會(huì)影響到其它的進(jìn)程。
    當(dāng)應(yīng)用程序池接收到HTTP請(qǐng)求后,交由在此應(yīng)用程序池中運(yùn)行的工作者進(jìn)程Worker Process: w3wp.exe來(lái)處理此HTTP請(qǐng)求。

  3. Worker Process: 當(dāng)工作者進(jìn)程接收到請(qǐng)求后,首先根據(jù)后綴找到并加載對(duì)應(yīng)的ISAPI擴(kuò)展 (如:aspx 對(duì)應(yīng)的映射是aspnet_isapi.dll),工作者進(jìn)程加載完aspnet_isapi.dll后,由aspnet_isapi.dll負(fù)責(zé)加載 ASP.NET應(yīng)用程序的運(yùn)行環(huán)境即CLR (.NET Runtime)。
    Worker Process運(yùn)行在非托管環(huán)境,而.NET中的對(duì)象則運(yùn)行在托管環(huán)境之上(CLR),它們之間的橋梁就是ISAPI擴(kuò)展。

  4. WAS(Web Admin Service):這是一個(gè)監(jiān)控程序,它一方面可以存取放在InetInfo元數(shù)據(jù)庫(kù)(Metabase)中的各種信息,另一方面也負(fù)責(zé)監(jiān)控應(yīng)用程序池(Application Pool)中的工作者進(jìn)程的工作狀態(tài)況,必要時(shí)它會(huì)關(guān)閉一個(gè)老的工作者進(jìn)程并創(chuàng)建一個(gè)新的取而代之。

再來(lái)看下網(wǎng)上對(duì)IIS7經(jīng)典模式下的圖解

IIS 7 應(yīng)用程序池的托管管道模式“經(jīng)典”模式也是這樣的工作原理。這種模式是兼容 IIS 6 的方式, 以減少升級(jí)的成本。

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

小插曲

場(chǎng)景假定:

截獲客戶(hù)端的請(qǐng)求,并對(duì)請(qǐng)求進(jìn)行重寫(xiě)。在IIS6中,請(qǐng)求的截獲動(dòng)作只能被限制在IIS加載aspnet_isapi.dll后,也就是說(shuō):如果該請(qǐng)求不是明確針對(duì)asp.net資源的請(qǐng)求(比如這個(gè)請(qǐng)求只是一個(gè)靜態(tài)文件的請(qǐng)求,如www.cnblogs.com/index.html,這時(shí)我們就便不能在代碼中編寫(xiě)截獲請(qǐng)求的邏輯,因?yàn)镮IS6是根據(jù)URL的后綴來(lái)映射并加載對(duì)應(yīng)的isapi的,如果一個(gè)請(qǐng)求的url 是:www.cnblogs.com/index.aspx,根據(jù)".aspx"這個(gè)后綴,IIS6可以得知這個(gè)請(qǐng)求是針對(duì)asp.net資源的,應(yīng)該加載aspnet_isapi.dll創(chuàng)建.net運(yùn)行時(shí)并運(yùn)行asp.net頁(yè)面的代碼,但很明顯,諸如"www.cnblogs.com/index.html"這種請(qǐng)求,IIS6通常認(rèn)為不是對(duì)asp.net資源的請(qǐng)求,因此不會(huì)加載 aspnet_isapi.dll來(lái)運(yùn)行asp.net,我們即使在asp.net頁(yè)面中編寫(xiě)了攔截請(qǐng)求的代碼,也不會(huì)被執(zhí)行。當(dāng)然,這里我說(shuō)通常是有原因的,因?yàn)槲覀兛梢栽贗IS6中添加通配符程序映射的方式,或者在web.config中對(duì)某種請(qǐng)求手動(dòng)添加處理程序的方式,來(lái)迫使IIS6為非 asp.net資源類(lèi)型的請(qǐng)求加載aspnet_isapi.dll。IIS6中對(duì)請(qǐng)求的執(zhí)行流程如上.

咦,有木有人和我一樣想到了URL Routing 和URL Rewriting ?

這里不做說(shuō)明,大叔手記16傳送門(mén):http://www.cnblogs.com/TomXu/archive/2011/12/27/2303486.html

這個(gè)問(wèn)題先放一下~~了解II7的集成模式也許可以有一些思緒 如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

讓我們?cè)賮?lái)看下IIS官網(wǎng)上對(duì)IIS7的圖解

傳送門(mén) :http://www.iis.net/learn/get-started/introduction-to-iis/introduction-to-iis-architecture

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

1、當(dāng)客戶(hù)端瀏覽器開(kāi)始 HTTP 請(qǐng)求一個(gè)WEB 服務(wù)器的資源時(shí),HTTP.sys 攔截到這個(gè)請(qǐng)求。

2、HTTP.sys 聯(lián)系 WAS 獲取配置信息。

3、WAS 向配置存儲(chǔ)中心(applicationHost.config)請(qǐng)求配置信息。

4、WWW 服務(wù)接收到配置信息,配置信息指類(lèi)似應(yīng)用程序池配置信息,站點(diǎn)配置信息等等。

5、WWW 服務(wù)使用配置信息去配置 HTTP.sys 處理策略。

6、WAS為請(qǐng)求創(chuàng)建一個(gè)進(jìn)程(如果不存在的話(huà))

7、工作者進(jìn)程處理請(qǐng)求并對(duì)HTTP.sys做出響應(yīng).

8、客戶(hù)端接受到處理結(jié)果信息。

IIS  7 應(yīng)用程序池的托管管道模式(集成模式)華麗的變身

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

IIS7中對(duì)asp.net的請(qǐng)求不再是分兩條處理管道,而是將asp.net和 IIS集成起來(lái),這樣做的好處是統(tǒng)一了請(qǐng)求驗(yàn)證工作,加強(qiáng)了asp.net對(duì)于請(qǐng)求的控制能力等等。在IIS7中,asp.net不再像IIS6一樣只限定于aspnet_isapi.dll中,而是被解放出來(lái),從IIS接收到HTTP請(qǐng)求開(kāi)始,即進(jìn)入asp.net的控制范圍,asp.net可以存在于一個(gè)請(qǐng)求在IIS中各個(gè)處理階段。甚至可以為部署在IIS7中的PHP應(yīng)用提供基于asp.net的驗(yàn)證身份驗(yàn)證功能(傳送門(mén):http://msdn.microsoft.com/zh-cn/magazine/cc135973.aspx)。

好吧,戛然而止一下,篇幅有限:IIS部分告一段落 留一些遐想空間.

再來(lái)分析ASP.NET的運(yùn)行機(jī)制

ASP.NET運(yùn)行機(jī)制

在IIS6圖示中我們分析到“ AppManagerAppDomainFactory 的 Create 方法為 Application 創(chuàng)建一個(gè) Application Domain;通過(guò) ISAPIRuntime 的  ProcessRequest 處理 Request,進(jìn)而將流程進(jìn)入到 ASP.NET Http Runtime Pipeline。”

下面我們來(lái)看一下AppDomain運(yùn)行過(guò)程圖示

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

AppDomain的作用,相信大家都很了解了吧.這里簡(jiǎn)明扼要的寫(xiě)幾點(diǎn):

一個(gè)AppDomain中的代碼創(chuàng)建的對(duì)象不能由另一個(gè)AppDomain中的代碼直接訪(fǎng)問(wèn)(只能使用按引用封送或者按值封送,起到了很好的隔離作用).

AppDomain可以卸載 CLR不支持從AppDomain中卸載一個(gè)程序集的能力,但可以告訴CLR卸載一個(gè)AppDomain,從而達(dá)到卸載當(dāng)前包含在該AppDomain內(nèi)的所有程序集.

AppDomain 可以單獨(dú)保護(hù) 當(dāng)宿主加載一些代碼之后,可以保證這些代碼不會(huì)被破壞(或讀取)宿主本身使用的一些重要的數(shù)據(jù)結(jié)構(gòu).

AppDomain可以單獨(dú)配置 設(shè)置主要影響CLR在AppDomain中加載程序集的方式,涉及搜索路徑、版本綁定重定向、卷影復(fù)制及加載器的優(yōu)化。

由以上幾點(diǎn)可以看出AppDomain確保了Windows系統(tǒng)及其中運(yùn)行的應(yīng)用程序的健壯性。AppDomain提供了保護(hù)、配置和終止其中每一個(gè)應(yīng)用程序所需的隔離性。

再來(lái)看下ProcessRequest的過(guò)程

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

簡(jiǎn)單分析一下上圖

ProcessRequest(HttpWorkerRequest wr)中判斷wr是否為null,然后判斷管線(xiàn)是否完整,再調(diào)用ProcessRequestNoDemand(wr)方法,

并判斷當(dāng)前RequestQueue 是否為null,接著計(jì)算等待時(shí)間并更新管線(xiàn)數(shù) CalculateWaitTimeAndUpdatePerfCounter(wr);

重置wr開(kāi)始時(shí)間wr.ResetStartTime();調(diào)用ProcessRequestNow(wr)方法,并調(diào)用ProcessRequestInternal(wr)方法

繼續(xù)圖例

如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制

ProcessRequestInternal方法如下:

private void ProcessRequestInternal(HttpWorkerRequest wr)     {         HttpContext context;         try         {             context = new HttpContext(wr, false);//由HttpWorkerRequest生成HttpContext         }         catch         {              //常見(jiàn)的400錯(cuò)誤,就是在這里捕捉到滴              wr.SendStatus(400, "Bad Request");             wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");             byte[] bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");             wr.SendResponseFromMemory(bytes, bytes.Length);             wr.FlushResponse(true);             wr.EndOfRequest();             return;         }         wr.SetEndOfSendNotification(this._asyncEndOfSendCallback, context);         Interlocked.Increment(ref this._activeRequestCount);         HostingEnvironment.IncrementBusyCount();         try         {             try             {                 this.EnsureFirstRequestInit(context);             }             catch             {                 if (!context.Request.IsDebuggingRequest)                 {                     throw;                 }             }             context.Response.InitResponseWriter();             IHttpHandler applicationInstance = HttpApplicationFactory.GetApplicationInstance(context);     //得到HttpApplication              if (applicationInstance == null)             {                 throw new HttpException(System.Web.SR.GetString("Unable_create_app_object"));             }             if (EtwTrace.IsTraceEnabled(5, 1))             {                 EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, applicationInstance.GetType().FullName, "Start");             }             if (applicationInstance is IHttpAsyncHandler)             {                 IHttpAsyncHandler handler2 = (IHttpAsyncHandler) applicationInstance;                 context.AsyncAppHandler = handler2;                 handler2.BeginProcessRequest(context, this._handlerCompletionCallback, context);//屆時(shí) HttpApplication處理請(qǐng)求             }             else             {                 applicationInstance.ProcessRequest(context);                 this.FinishRequest(context.WorkerRequest, context, null);             }         }         catch (Exception exception)         {             context.Response.InitResponseWriter();             this.FinishRequest(wr, context, exception);         }     }

再看下GetApplicationInstance(context) 實(shí)例化Application的方法

View Code    internal static IHttpHandler GetApplicationInstance(HttpContext context)   {       if (_customApplication != null)       {           return _customApplication;       }       if (context.Request.IsDebuggingRequest)       {           return new HttpDebugHandler();       }       _theApplicationFactory.EnsureInited();       _theApplicationFactory.EnsureAppStartCalled(context);       return _theApplicationFactory.GetNormalApplicationInstance(context);   }

最后調(diào)用的GetNormalApplicationInstance方法中對(duì)當(dāng)前空閑的application數(shù)目進(jìn)行判斷,調(diào)用

application.InitInternal(context, this._state, this._eventHandlerMethods)方法,

this.InitModules()初始化所有的Modules,包含用戶(hù)自定義的HttpModules

this._stepManager.BuildSteps(this._resumeStepsWaitCallback);//管道事件序列

貼一下源碼:

internal override void BuildSteps(WaitCallback stepCallback)    {        ArrayList steps = new ArrayList();        HttpApplication app = base._application;        bool flag = false;        UrlMappingsSection urlMappings = RuntimeConfig.GetConfig().UrlMappings;        flag = urlMappings.IsEnabled && (urlMappings.UrlMappings.Count > 0);        steps.Add(new HttpApplication.ValidatePathExecutionStep(app));        if (flag)        {            steps.Add(new HttpApplication.UrlMappingsExecutionStep(app));        }        app.CreateEventExecutionSteps(HttpApplication.EventBeginRequest, steps);        app.CreateEventExecutionSteps(HttpApplication.EventAuthenticateRequest, steps);        app.CreateEventExecutionSteps(HttpApplication.EventDefaultAuthentication, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostAuthenticateRequest, steps);        app.CreateEventExecutionSteps(HttpApplication.EventAuthorizeRequest, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostAuthorizeRequest, steps);        app.CreateEventExecutionSteps(HttpApplication.EventResolveRequestCache, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostResolveRequestCache, steps);        steps.Add(new HttpApplication.MapHandlerExecutionStep(app));        app.CreateEventExecutionSteps(HttpApplication.EventPostMapRequestHandler, steps);        app.CreateEventExecutionSteps(HttpApplication.EventAcquireRequestState, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostAcquireRequestState, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPreRequestHandlerExecute, steps);        steps.Add(new HttpApplication.CallHandlerExecutionStep(app));        app.CreateEventExecutionSteps(HttpApplication.EventPostRequestHandlerExecute, steps);        app.CreateEventExecutionSteps(HttpApplication.EventReleaseRequestState, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostReleaseRequestState, steps);        steps.Add(new HttpApplication.CallFilterExecutionStep(app));        app.CreateEventExecutionSteps(HttpApplication.EventUpdateRequestCache, steps);        app.CreateEventExecutionSteps(HttpApplication.EventPostUpdateRequestCache, steps);        this._endRequestStepIndex = steps.Count;        app.CreateEventExecutionSteps(HttpApplication.EventEndRequest, steps);        steps.Add(new HttpApplication.NoopExecutionStep());        this._execSteps = new HttpApplication.IExecutionStep[steps.Count];        steps.CopyTo(this._execSteps);        this._resumeStepsWaitCallback = stepCallback;    }

到這里想必能夠使大家對(duì)ASP.NET管道機(jī)制能夠有一個(gè)簡(jiǎn)單的回顧.當(dāng)然還有很多地方?jīng)]有詳細(xì)分析。

再來(lái)總結(jié)一下IIS運(yùn)行過(guò)程及ASP.NET管道機(jī)制:

Request&rarr; (Internet )  HTTP.sys 監(jiān)聽(tīng) &rarr; WAS (IIS6 web Admin Service /IIS7 (Windows Activation Service) 接收請(qǐng)求

&rarr;(傳入)Application Pool's &rarr; w3wp.exe(檢查URL后綴)

&rarr;(加載)ISAPI擴(kuò)展[aspnet_isapi.dll] &rarr; 注冊(cè)映射

構(gòu)造HttpRuntime類(lèi) &rarr;ProcessRequest方法

HttpContext實(shí)例產(chǎn)生(Request,Response,Session  and so on&hellip;)

HttpRuntime 調(diào)用 HttpApplicationFactory加載HttpApplication對(duì)象

穿越HttpModule到達(dá)HttpHandler

簡(jiǎn)單用140個(gè)字符(即一條微博的字?jǐn)?shù)如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制)概括:

Request&rarr; (Internet ) HTTP.sys &rarr;(WAS)&rarr;Application Pool's &rarr; w3wp.exe&rarr;ISAPI&rarr; Map&rarr; (Pipeline)HttpWorkerRequest&rarr;AppDomain&rarr;HttpRuntime&rarr;ProcessRequest()&rarr; HttpContext(Request,Response)&rarr; HttpRuntime&rarr;HttpApplicationFactory&rarr;HttpApplication&rarr; HttpModule&rarr;HttpHandler&rarr;EndRequest

以上為個(gè)人學(xué)習(xí)摘要,如有錯(cuò)誤,歡迎指正!!

補(bǔ)充

1:剛剛看到dudu發(fā)的一個(gè)閃存,里面提到了Application pool 與 AppDomain 的區(qū)別 來(lái)自stackoverflow,希望對(duì)大家有所幫助.

2:WAS縮寫(xiě)在IIS6中的指的是(Web Admin Service),在IIS7中指的是(Windows Activation Service)  縮寫(xiě)一樣.這個(gè)在寫(xiě)文章的時(shí)候注意到過(guò),但是沒(méi)有深入考慮. 理解不是很到位.  暫不妄下斷言.  歡迎斧正!! :-)

關(guān)于如何理解HTTP協(xié)議/IIS 原理及ASP.NET運(yùn)行機(jī)制就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI