什么是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 。