這半年來,在開發ASP.NET Web API及SignalR的過程常看到一枚生冷術語--OWIN,不知其所以然好一陣子,今天花點功夫粗略理解一番,特筆記備忘。

OWIN(Open Web Interface for .NET)是一套開放網站介面標準,重新定義了.NET Web Application與Web Server的溝通介面。就系統架構觀點,介面被抽取出來獨立意味著"抽換"的可能性,用白話解釋,意思是ASP.NET程式可以不依賴System.Web.dll,不侷限於IIS,放在Console程式裡跑Self-Hosting模式,甚至透過Kayak網站伺服器在*nix系統運作,都不再是神話。

由下到上,OWIN架構區分為四層:

  • Host
    最底層,負責載入、啟動及關閉OWIN元件
  • Server
    負責連上TCP Port,建構OWIN Pipeline環境以處理Request
  • Middleware
    所有在OWIN Pipeline中Request處理模組的統稱,小到很簡單的資料壓縮模組,大至ASP.NET Web API都算。
  • Application
    依專案需求所開發的應用程式碼

擺脫System.Web.dll的另一項好處: 網站基底架構由龐大的官方Framework轉化成多個中小型模組,可以個別機動抽換更新,不需要苦苦等待官方改版。

現今ASP.NET相關技術中,由ASP.NET Web API跨出第一步,完全排除對System.Web.dll的依賴。.NET社群仿效Ruby Rack的精神,為.NET網站定義了OWIN,而Katana專案則是微軟依OWIN規格所實作的元件,包含Host、Server、身分認證元件... 等,ASP.NET Web API與SignalR則是目前應用OWIN標準的經典範例。

光說不練令人心虛,總得來個簡單演練才踏實,以下是個範例,利用Microsoft.Owin.Hosting.WebApp + Nancy(一套支援OWIN的迷你Web Server模組),在Console Application模擬簡易Web Server。

開啟一個Console Application專案,利用NuGet安裝以下套件:

Microsoft.Owin.Hosting

Microsoft.Owin.Host.HttpListener

Nacy.Owin

簡單寫幾行程式:

  1. 定義MyStartup類別,在其中設定Server要掛載的模組,UseNancy是Nancy提供的Extension Method,一行就搞定Nancy設定。
  2. 定義HomeModule,繼承NancyModule,在建構式中宣告Get["/"]拋回HTML、Post["/money"]傳回Server時間,我們為這個小Web加入 GET / 及 POST /money 兩個功能。
  3. WebApp.Start<MyStarup>("http://+:1234")聆聽本機的1234 Port開始執行網站功能,透過Console.ReadLine()待使用者按Enter後結束服務。(記得要netsh開權限,這點之前提過)
  4. 打完收工。
using Microsoft.Owin.Hosting;
using Nancy;
using Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace OWINLab
{
    class Program
    {
        static void Main(string[] args)
        {
            //記得開放Binding權限
            //netsh http add urlacl url=http://+:port_number/ user=machine\username
            using (WebApp.Start<MyStartup>("http://+:1234"))
            {
                Console.WriteLine("OWIN self-hosting, press enter to exit");
                Console.ReadLine();
            }
        }
    }
 
    public class HomeModule : NancyModule
    {
        public HomeModule()
        {
            Get["/"] = x =>
            {
                return @"
<html><body>
<input type='button' value='Show Me the Money'></input>
<script src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js'></script>
<script>
$(':button').click(function() {
    $.post('/money',{},function(m) {
        alert(m);
    });
});
</script>
</body></htmol>";
            };
            Post["/money"] = x =>
            {
                return "MONEY @ " + DateTime.Now.ToString("HH:mm:ss");
            };
        }
    }
 
    public class MyStartup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseNancy();
        }
    }
}

就這樣誕生一個超簡單的小Web,很感人吧!

【延伸閱讀】


Comments

# by 阿翰

驚呆了... 一直以來依靠tomcat、iis來架設網站 沒想到有一天可以用這麼簡單就可以寫一個動態web

# by 阿天

雖然沒學過Web但感覺很神奇

# by 阿承

請問是否有辦法監聽所有的來源 例如 http://* 我目前有個案子 要針對所有的要求做處理 例如:非http則變更https 設定在防火牆之後先作業 還沒到IIS之前 要能work所有的站台 目前看文章(和官方的)沒有可以catch any 而且使用中的host還不能監聽= = 想要在很底層去處理

# by Jeffrey

to 阿承,這已不太像該自己寫程式搞定的需求,聽起來有 Proxy 的味道,再不然要學 WireShark 或 Fiddler 從攔截封包下手。如真要自幹,可考慮 Fiddler SDK。

# by jt.chou

to 阿承,你需要的是 Nginx http > https 其實只是一個跳轉

Post a comment