標籤:style blog http color 使用 os
上一回合中,我們講解了Linux.NET面對OWIN需要做出的準備,以及介紹了如何將兩個支援OWIN協議的架構:SignalR以及NancyFX以OwinHost的方式部署到Linux.NET當中。這一章,我們將對架構與OwinHost之間怎麼通過OWIN協議作出解析。
本章我們將討論學習:
(1)、串連兩世界之門——“Middleware“
(2)、轉動大門的鑰匙,開啟無盡的財寶
(3)、適配器?轉換插頭
相關範例程式碼,可以點擊這裡進行下載。
1、充當”門“的”Middleware“
英文名”Middleware“,中文名”中介軟體“,要瞭解什麼是Middleware,我們先看看OWIN協議中的分層。
為OWIN分層的一個簡圖。最下的一層是我們的作業系統,Linux、Windows、Unix、Mac或其他;對上一層則是運行於作業系統中的OwinHost;再往上一層也就是紫色那層是基於OWIN協議建立的基礎架構;而最頂層則是我們基於這些OWIN協議的架構所誕生的應用程式(直接操作OWIN字典的暫不記錄在圖中)。
拋開最頂和最底兩層不管,當使用者從用戶端發起一請求,經過漫長的網路,到達目標主機時,請求將被並且僅能被OwinHost捕獲,因為只有OwinHost在持續的不斷監聽連接埠。雖然請求已經被OwinHost捕獲,但是OwinHost並沒有能力對這個剛捕獲的請求做出處理(這裡特指需要經過OWIN架構及相關應用程式處理的請求)即使它知道自身有請求需要處理。
同樣的,我們再把目光轉到OWIN架構,它是我們的”處理中樞“,它能夠對我們把我們的輸入通過適當的計算之後把正確的答案輸出來,但是它也有一個缺點,那就是它自身沒有辦法收集”相關資訊“,也就是它自己並不能產生出”輸入“。
這就好比人的大腦與其他器官,OWIN架構是我們的”大腦“,OwinHost則是我們的”器官“,沒有了大腦我們的其他器官也無法正常運行(當然咯,有點功能不需要大腦,就像有些OwinHost處理靜態資源不需要經過OWIN架構一樣),沒有了其他“器官”的支援“大腦”也無法發揮作用甚至會死亡(沒有宿主,OWIN架構也無法運行)。
因此,我們需要有相應的“神經”來連通我們的“器官”與“大腦”之間的通訊。而Middleware發揮的就是這種作用,它是串連OwinHost與OWIN架構的門,OwinHost把捕獲到的請求通過自身的處理後通過這扇門推送到OWIN架構中;而OWIN架構也自己對請求計算後得出的響應通過這扇門返回到OwinHost中,再由OwinHost推送到使用者手上。
而事實上,Middleware作為一扇串連OwinHost與OWIN架構的門,讓這兩個世界得以交流以外,還發揮著另外一個作用,那就是規定了統一的資訊出入口,所有的請求響應均只能夠通過這扇門傳遞,這或者可以更方便的對一些敏感資訊、惡意代碼之流的資料進行攔截與過濾。
2、轉動我們手中的鑰匙
正如上一節中最後所講到的一樣,Middleware作為OWIN架構與OwinHost的唯一通道,這意味著無論是SignalR、NancyFX、Webapi、FubuMVC或是其他,它們所站立的起點高度都是一致的,我們只要把能握住Middleware,就相當於把握住了大門的鑰匙,我們也可以做出我們自己的架構出來。這也是我在上一回合中所提到OWIN協議給我們帶來的好處中的第二點:“它給鼓勵了一批人把自己的想法變成現實”。
本節我們將簡述如何直接操作OWIN字典,直接和OwinHost進行通訊。
首先我們需要在Visual Studio中建立我們的項目,然後通過NuGet獲得OWIN:
然後我們建立一個類,並以它作為我們的Middleware:
using System;using System.Collections.Generic;using System.IO;using System.Text;using System.Threading.Tasks;namespace Demo1{ using AppFun = Func<IDictionary<string, object>, Task>; public class MyMiddleware { private readonly AppFun _env; public MyMiddleware(AppFun env) { if (env == null) throw new ArgumentNullException("OWIN環境參數為空白"); this._env = env; } public Task Invoke(IDictionary<string, object> env) { var responseBody = "Linux.NET 學習手記(8) --小蝶驚鴻"; var responseBodyBytes = Encoding.UTF8.GetBytes(responseBody); ((IDictionary<string, string[]>)env["owin.ResponseHeaders"]).Add("Content-Type", new string[] { "text/html; charset=utf-8" }); ((Stream)env["owin.ResponseBody"]).Write(responseBodyBytes, 0, responseBodyBytes.Length); return this._env(env); } }}MyMiddleware
這裡要對代碼進行一番的解析:
(1)、這是我們的Middleware,所有來自於OwinHost的請求資料以及OWIN架構響應的資料都要通過這個類來進行統一中轉處理。
(2)、IDictionary<string, object>實則為OWIN字典,裡麵包含了基於OWIN協議的用於OwinHost與OWIN架構之間通訊的資料資訊。
(3)、程式啟動時,OwinHost會先執行個體化這個類(實則調用Startup中的Configuration,然後執行個體化這個類,稍後我們會對此進行講述),繼而執行這個類的建構函式對Environment(也就是那個env)進行初始化。
(4)、每次OwinHost捕獲到請求之後,會調用Invoke,OWIN字典會攜帶請求進入該方法,程式處理完成之後,OWIN字典則會攜帶OWIN架構的響應離開該方法。
建立好我們的Middleware之後,我們需要在項目的根目錄建立一個名為“Startup”的類,並在此類裡面建立一個名為“Configuration”的方法。
namespace Demo1{ using Owin; public class Startup { public void Configuration(IAppBuilder app) { app.Use(typeof(MyMiddleware)); } }}Startup.cs
這裡也要為這個類作出一番解析:
OwinHost嘗試驅動OWIN架構時,它會嘗試尋找Startup,並啟用裡面的Configuration,繼而啟用我們自訂的Middleware。OwinHost啟用我們的Middleware之後,OwinHost與OWIN架構之間就建立了串連,串連這兩個世界的“門”也就開啟了。
在範例程式碼中,Demo1為講解如何通過簡單的操作OWIN字典擷取並返回我們想要輸出的結果。
Demo2則是類比ASP.NET MVC的路由功能,OwinHost啟用Startup時,程式會對自身的程式集進行反射,找出所有以“Controller”結尾的類,並把裡面的方法註冊到路由字典中。當有來自於使用者的請求,程式則會自動的拆解URL並在路由字典中判斷是否存在改頁面,存在則繼而啟用相應的方法(Action),不存在則導向到404頁面。其效果如所示:
成功的路由導向到Home/Index 頁面
訪問一個不存在的地址,路由導向到一個404的小動畫。
事實上,由於我們是基於OWIN協議直接操作OWIN字典所誕生的小Demo,因此我們是可以以一種無障礙的方式直接將項目發布到Linux.NET中運行。
3、充當轉換插頭角色的適配器
可能有細心而又愛動腦筋的讀者不禁問到,關於那兩個Demo(也能泛指其他所有的OWIN架構),OwinHost已經有了(Katana或者Jexus或其他),Middleware也由我們自行提供,不是OwinHost就可以與OWIN架構之間作出通訊了嗎?上一回合中所出現的適配器又是怎麼回事?為什麼沒有見到Windows版的適配器?
在解析這個之前,我先上一張能夠很恰當比喻適配器的圖片:
這是我隨手從網上找來的圖片,用過它的讀者很容易就能夠分辨出來它是一個轉換插頭,它能夠把各種類型的原插口轉換成通用的插口。對的,沒錯,如果以簡單的方式來理解,適配器所起的所用正式OwinHost與OWIN架構之間的轉換插頭,它把OwinHost中所提供的未經處理資料格式化成OWIN字典供OWIN架構使用。這就是簡單的理解方式。
更深入的方式來理解,適配器發揮著兩個重要的作用,除了簡單理解中所講述的作用以外,它還充當著讓OwinHost成功驅動Startup並啟用Configuration的關鍵。有興趣的讀者可以開啟Jexus針對於OWIN架構的適配器,你會發現原來它也是通過反射尋找Startup類並啟用裡面的Configuration來建立Middleware並建立串連的,瞭解了這一點之後,我們可以通過修改適配器的源碼來更改OwinHost嘗試驅動OWIN架構時最先啟用的類,我們可以根據自己的愛好把“Startup”這個名字改為“Breakdown”、“Sunday”或者“ILoveChina”甚至“ILoveXiaodiejinghong”,也可以把“Configuration”改為其他……總之你喜歡的。
至於為何Katana沒有適配器,我這裡只能說:“可能已經內建了吧”(具體還需要各位讀者查看源碼,我沒有查看過,因此沒有發言權)。
好的,兩回合文章我們簡單的認知了一些關於OWIN的事情,OWIN作為微軟提出一套重要協議具有重大的戰略意義。不多說了,我們下回再見吧。謝謝。