從《ASP.NET Core管道深度剖析(1):采用管道處理HTTP請求》我們知道ASP.NET Core請求處理管道由一個服務器和一組有序的中間件組成,所以從總體設計來講是非常簡單的,但是就具體的實現來說,由于其中涉及很多對象的交互,我想很少人能夠地把它弄清楚。如果想非常深刻地認識ASP.NET Core的請求處理管道,可以分兩個步驟來進行,我們首先可以在忽略細節的前提下搞清楚管道處理HTTP請求的總體流程,然后再此基礎上補充之前遺漏的細節。為了讓讀者朋友們能夠更加容易地理解管道處理HTTP請求的總體流程,我們根據真實管道的實現原理再造了一個“模擬管道”。[模擬管道以及建立在它之上的圖片發布應用源代碼從這里下載]
對于我們再造的迷你版本的管道,它不僅僅體現了真實管道中處理HTTP請求的流程,對于其中涉及的接口和類型,我們基本上采用了相同的命名。但是為了避免很多“細枝末節”對我們的理解造成干擾,我們會進行最大限度的裁剪。對于大部分方法,我們只會保留最核心的邏輯;對于一些接口,我們設置會提出掉一些與核心流程無關的成員。在通過這個模擬的管道講解HTTP請求的總體處理流程之前,我們先來看看如何在它基礎上開發一個簡單的應用。
我們在這個模擬管道上開發一個簡單的應用來發布圖片。具體的應用場景是這樣:我們將圖片文件保存在服務器上的某個目錄下,客戶端可以通過發送HTTP請求并在請求地址上指定文件名的方式來獲取目標圖片。如右圖所示,我們利用瀏覽器向針對某張圖片的地址(“http://localhost:3721/girl”)發送請求后,獲取到的目標圖片(girl.jpg)會直接顯示到瀏覽器上。
由于我們模擬的管道采用與真實管道一致的API,所以兩種采用的編程模式也是一致的。對于這個用于發布圖片的應用來說,它也和我們上面演示的Hello World程序一樣有兩個基本的類型構成。一個是定義了入口Main方法的Program,另一個則是作為啟動類型的Startup。
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: new WebHostBuilder()
6: .UseServer(new HttpListenerServerFactory("http://localhost:3721/"))
7: .UseStartup(typeof(Startup))
8: .Build()
9: .Start();
10: }
11: }
12:
13: public class Startup
14: {
15: public void Configure(IApplicationBuilder app)
16: {
17: app.UseImages(@"c:\images");
18: }
19: }
如上面的代碼片斷所示,我們在Main方法中創建了一個WebHostBuilder對象,在調用其Build方法創建應用宿主的WebHost之前,我們調用其UseServer方法注冊了一個用于創建服務器的HttpListenerServerFactory對象。HttpListenerServerFactory對象用于創建一個名為HttpListenerServer的服務器,這是我們自己定義的服務器,它利用一個HttpListener對象實現了針對HTTP請求的監聽、接收和最終的響應。HttpListenerServerFactory構造函數指定的HttpListener的監聽地址。
在完成了服務器注冊之后,我們調用UseStartup方法將Startup作為啟動類型。通過上面的介紹我們知道,啟動類型的目的在于通過注冊相應中間件的方式對構建的管道進行定制。對于我們演示的這個應用來說,管道對HTTP請求的處理體現在如何根據請求地址解析出對應圖片的文件路徑,并將文件的內容作為請求的響應。完成這項操作的中間件是通過調用我們自定義的擴展方法UseImages進行注冊的,該方法的參數表示存放圖片的目錄(c:\images)。
總的來說,請求處理管道涉及到四個核心的對象,它們分別是WebHostBuilder、WebHost、Server和HttpApplication,它們之間具有如右圖所示的關系。我們通過WebHostBuilder來創建WebHost,并領用后者來構建請求處理管道。 請求處理管道通過一個Server和一個HttpApplication對象組成,后者是對所有注冊的中間件的封裝。當WebHost被啟動的時候,它會創建Server和HttpApplication對象,并將后者作為參數調用Server的Start方法以啟動服務器。啟動后的Server開啟監聽請求并利用HttpApplication來處理接收到請求。當HttpApplication完成了所有請求處理工作之后,它會利用Server完成對請求的最終響應。
我們將在后續的兩篇文章對模擬管道的設計和實現作詳細介紹,相信讀者朋友們據此可以對實現在ASP.NET Core管道中的請求處理流程以及管道自身的創建流程有一個深刻的認識,如果大家對此有興趣,敬請關注本系列后續文章。
一、采用管道處理HTTP請求
二、創建一個“迷你版”的管道來模擬真實管道請求處理流程
三、管道如何處理HTTP請求的
四、管道是如何被創建出來的
文章列表