什麼是OWIN
OWIN是Open Web Server Interface for .NET的首字母縮寫,他的定義以下:緩存
OWIN在.NET Web Servers與Web Application之間定義了一套標準接口,OWIN的目標是用於解耦Web Server和Web Application。基於此標準,鼓勵開發者開發簡單、靈活的模塊,從而推動.NET Web Development開源生態系統的發展。服務器
正如你看到的這樣,OWIN是接口、契約,而非具體的代碼實現,僅僅是規範(specifications),因此要實現自定義基於OWIN的Web Server必需要實現此規範。併發
歷時兩年(2010-2012),OWIN的規範終於完成而且當前版本是1.0,在OWIN的官網上能夠看到更具體的信息。mvc
爲何咱們須要OWIN
過去,IIS做爲.NET 開發者來講是最經常使用的Web Server(沒有之一),源於微軟產品的緊耦合關係,咱們不得不將Website、Web Application、Web API等部署在IIS上,事實上在2010年前並無什麼不妥,但隨着近些年來Web的發展,特別是移動互聯網飛速發展,IIS做爲Web Server已經暴露出他的不足了。主要體如今兩個方面,ASP.NET (System.Web)緊耦合IIS,IIS緊耦合OS,這就意味着,咱們的Web Framework必須部署在微軟的操做系統上,難以跨平臺。app
ASP.NET 和 IIS
咱們知道,不論是ASP.NET MVC 仍是ASP.NET WEB API 等都是基於ASP.NET Framework的,這種關係從前綴就能夠窺倪出來。而ASP.NET的核心正是System.Web這個程序集,並且System.Web緊耦合IIS,他存在於.NET Framework中。因此,這致使了Web Framework嚴重的侷限性:異步
- ASP.NET 的核心System.Web,而System.Web緊耦合IIS
- System.Web 是.NET Framework重要組成,已有15年以上歷史,沉重、冗餘,性能差,難於測試,約2.5M
- System.Web要更新和發佈新功能必須等待.NET Framework發佈
- .但NET Framework是Windows的基礎,每每不會隨意更新。
因此要想獲取最新的Web Framework是很是麻煩的,幸運的事,微軟已經意識到了問題的嚴重性,最新的Web Framework都是經過Nuget來獲取。ide
固然這是一部分緣由,還有一層緣由是ASP.NET & IIS實在太過於笨重,如何講呢?post
複雜的生命週期已成爲累贅?簡單來講,當請求到達服務器時,Windows內核組件HTTP.SYS組件捕獲請求,他會分析請求並決定是否交給IIS來處理,當請求到達IIS以後,IIS會根據處理程序映射來匹配請求並交給對應的程序集(實現了ISAPI接口,好比咱們熟知的aspnet_isapi.dll是專門用來處理ASP.NET Application)處理,最後加載了CLR運行環境,將請求交給aspnet_wp.exe去處理,這時複雜的ASP.NET生命週期每每使人頭大,但事實上有不少時候咱們並不須要他。
以下圖所示ASP.NET Architecture:
打開IIS,你會發現他提供了很是豐富的功能:緩存、身份驗證、壓縮、加密等。但隨着移動互聯網蓬勃的發展,特別是HTML 5愈來愈成熟的今天,咱們看到愈來愈多的操做發生在客戶端,而不是沉重的從服務器產生HTML返回,更多的是經過異步AJAX返回原生的數據。同理,對於 APP來講咱們只須要Mobile Service返回數據。顯然IIS顯得笨重了點,並且IIS做爲微軟產品系的一環,耦合程度過高。因此咱們迫切須要輕量、快速、可擴展的宿主來承載Web Application和Web Service。
IIS 和 OS
IIS必須是安裝並運行在Windows操做系統中,這是微軟產品的一向風格,環環相套,但不得不考慮他們的限制和侷限性:
- IIS每每和操做系統(Windows Server)綁定在一塊兒,這意味着對於一些新功能如WebSocket Protocol ,咱們不得不等待操做系統Windows Sever 20十二、Windows 8的發佈(IIS 8.0)。
- 爲了使用WebSocket這類新特性,他僅被IIS 8.0支持,以下所示:
這時你不得不去升級IIS,但升級操做系統可能會引起舊系統的不穩定性,因此要想平穩的升級IIS並非簡單的。
- IIS做爲經典的Web Server必須安裝在Windows系統中,Windows Server須要受權使用。
正是因爲微軟產品系緊耦合的關係,才形成跨平臺上的不足,這也是被飽受詬病。因此咱們須要OWIN來解耦,在面向對象的世界裏,接口每每是解耦的關鍵,以下圖所示:
使用OWIN,Web Framework再也不依賴IIS和OS,這意味着你能使用任何你想的來替換IIS(好比:Katana或者Nowin),而且在必要時隨時升級,而不是更新操做系統。固然,若是你須要的話,你能夠構建自定義的宿主和Pipeline去處理Http 請求。
這一切的改變都是因爲OWIN的出現,他提供了明晰的規範以便咱們快速靈活的去擴展Pipeline來處理Http請求,甚至能夠不寫任何一句代碼來切換不一樣的Web Server,前提是這些Web Server 遵循OWIN規範。
OWIN的規範
如今咱們已經瞭解了什麼是OWIN已經爲何須要OWIN,如今是時候來分析一下OWIN的規範了。
OWIN Layers
實際上,OWIN的規範很是簡單,他定義了一系列的層(Layer),而且他們的順序是以堆(Stack)的形式定義,以下所示。OWIN中的接口被稱之爲應用程序委託或者AppFunc,用來在這些層之間通訊。
OWIN定義了4層:
Host:主要負責應用程序的配置和啓動進程,包括初始化OWIN Pipeline、運行Server。
Server:這是實際的Http Server,綁定套接字並監聽的HTTP請求而後將Request和Response的Body、Header封裝成符合OWIN規範的字典併發送到OWIN Middleware Pipeline中,最後Application爲Response Data填充合適的字段輸出。
Middleware:稱之爲中間件、組件,位於Server與Application之間,用來處理髮送到Pipeline中的請求,這類組件能夠是簡單的Logger或者是複雜的Web Framework好比Web API、SignalR,只要Sever鏈接成功,Middleware中間件能夠是任何實現應用程序委託的組件。
Application:這是具體的應用程序代碼,可能在Web Framework之上。對於Web API、SignalR這類Web Framework中間件而言,咱們僅僅是改變了他們的託管方式,而不是取代ASP.NET WEB API、SignalR原先的應用程序開發。因此該怎麼開發就怎麼開發,只不過咱們將他們註冊到OWIN Pipeline中去處理HTTP 請求,成爲OWIN管道的一部分,因此此處的Application即正在乎義上的處理程序代碼。
Application Delegate
OWIN規範另外一個重要的組成部分是接口的定義,用於Server和Middleware的交互。他並非嚴格意義上的接口,而是一個委託而且每一個OWIN中間件組件必須提供。
從字面上理解,每一個OWIN中間件在必須有一個方法接受類型了IDictionary<string,object>的變量(俗稱環境字典),而後必須返回Task來異步執行。
Environment Dictionary
環境字典包含了Request、Response全部信息以及Server State。經過Pipeline,每一箇中間件組件和層均可以添加額外的信息,但環境字典定義了一系列強制必須存在的Key,以下所示:
Request Data:
|
|
Value Description |
|
|
A Stream with the request body, if any. Stream.Null MAY be used as a placeholder if there is no request body. See Request Body. |
|
|
An IDictionary<string, string[]> of request headers. See Headers. |
|
|
A |
|
|
A |
|
|
A |
|
|
A |
|
|
A |
|
|
A |
Response Data:
|
|
Value Description |
|
|
A Stream used to write out the response body, if any. See Response Body. |
|
|
An IDictionary<string, string[]> of response headers. See Headers. |
|
|
An optional |
|
|
An optional |
|
|
An optional |
Other Data:
|
|
Value Description |
|
|
A CancellationToken indicating if the request has been cancelled/aborted. See Request Lifetime. |
|
|
The string |
小結
這些規範看起來可能簡單到微不足道,但OWIN的思想就是簡單、靈活——經過要求OWIN中間件只依賴AppFun類型,爲開發基於OWIN的中間件提供了的最低門檻。同時,經過使用環境字典在各個中間件之間進行信息的傳遞,而非傳統ASP.NET(System.Web)中使用HttpContext貫穿ASP.NET整個生命週期來傳遞。
既然OWIN是規範,而非真正實現,因此是沒法使用在項目中的,若要使用OWIN,必需要實現他,因此這也是接下來我想聊的,OWIN的實現:Katana 。