深入理解 OWIN 中的 Host 和 Server
The Open Web Interface for .NET (OWIN),注意单词为大写,之前好像都写成了 Owin,但用于项目的时候,可以写成:Microsoft.Owin.*。
OWIN 体系结构图(简化版):

ASP.NET 5 中 Server 和 Host 相关程序包(New/Old):
- Microsoft.AspNet.Hosting:Microsoft.Owin.Hosting
- Microsoft.AspNet.Server.IIS:Microsoft.Owin.Host.SystemWeb
- Microsoft.AspNet.Server.WebListener:Microsoft.Owin.Host.HttpListener
- Microsoft.AspNet.StaticFiles:Microsoft.Owin.StaticFiles
- Microsoft.AspNet.Security:Microsoft.Owin.Security
- Microsoft.AspNet.Diagnostics:Microsoft.Owin.Diagnostics
- ...
另外,在 ASP.NET 5 中,还有一个 K 命令,对应原 OWIN 中的 OwinHost.exe。
在 OWIN 的体系结构中,结合 ASP.NET 5 相关程序包,Host 和 Server 的概念,Microsoft.AspNet.Hosting、Microsoft.AspNet.Server.IIS、Microsoft.AspNet.Server.WebListener 等程序包,然后还有 Web Server(IIS、Apache 等),其实它们之间的关系很容易搞混,尤其是在理解 ASP.NET 5 的运行机制或在其项目发布的时候,如果不能很好的理解它们之间的相互关系,将是一个很大的隐患,下面我们根据 Host 和 Server 来分别理解他们。
Host
Host(主机):运行应用程序的进程,可以是从 IIS 或独立可执行文件到自己的自定义程序的任何内容。主机负责启动、加载其他 OWIN 组件和正常关闭,主机一般可以看作是服务器的操作系统提供的进程。
从概念上理解,Host 其实就是一个进程,用于管理 OWIN 组件的一些操作,对于现在的 ASP.NET 5 应用程序部署来说,Host 一般有两个选择:Self-Host 和 IIS。
先来看一下采用 Self-Host 的一段 project.json 配置:
{
"webroot": "wwwroot",
"dependencies": {
"Microsoft.AspNet.Hosting": "1.0.0-beta1",
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta1"
},
"commands": {
/* Change the port number when you are self hosting this application */
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
}
}
这是 ASP.NET 5 项目中采用 Self-Host 方式最简单的一个配置,因为有了 K Commands(OwinHost.exe),所以我们不需要在 Startup Configure 进行如下配置:
var baseAddress = new Uri("http://localhost:5000");
var config = new HttpSelfHostConfiguration(baseAddress);
OwinHost.exe 命令说明:

咋一看,和 K Commands 非常类似,其实就是从 OwinHost 演化而来的,在上面 project.json 配置中,我们只加载了两个程序包,其中 Microsoft.AspNet.Server.WebListener 是 OWIN 中 Server 的概念,是创建 ASP.NET 5 项目的默认服务器,这个后面再说,那 Microsoft.AspNet.Hosting 是什么?官方说明为:The Hosting repo contains code required to host an ASP.NET vNext application, it is the entry point used when self-hosting an application. 什么意思呢?我们看一下 Microsoft.AspNet.Hosting/Program.cs 的源码,就知道了:
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Framework.ConfigurationModel;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.Logging;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.Hosting
{
public class Program
{
private const string HostingIniFile = "Microsoft.AspNet.Hosting.ini";
private readonly IServiceProvider _serviceProvider;
public Program(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public void Main(string[] args)
{
var config = new Configuration();
if (File.Exists(HostingIniFile))
{
config.AddIniFile(HostingIniFile);
}
config.AddEnvironmentVariables();
config.AddCommandLine(args);
var services = HostingServices.Create(_serviceProvider, config)
.BuildServiceProvider();
var appEnv = services.GetRequiredService<IApplicationEnvironment>();
var hostingEnv = services.GetRequiredService<IHostingEnvironment>();
var context = new HostingContext()
{
Services = services,
Configuration = config,
ServerName = config.Get("server"), // TODO: Key names
ApplicationName = config.Get("app") // TODO: Key names
?? appEnv.ApplicationName,
EnvironmentName = hostingEnv.EnvironmentName,
};
var engine = services.GetRequiredService<IHostingEngine>();
var loggerFactory = services.GetRequiredService<ILoggerFactory>();
var appShutdownService = _serviceProvider.GetRequiredService<IApplicationShutdown>();
var shutdownHandle = new ManualResetEvent(false);
var serverShutdown = engine.Start(context);
appShutdownService.ShutdownRequested.Register(() =>
{
try
{
serverShutdown.Dispose();
}
catch (Exception ex)
{
var logger = loggerFactory.Create<Program>();
logger.WriteError("TODO: Dispose threw an exception", ex);
}
shutdownHandle.Set();
});
var ignored = Task.Run(() =>
{
Console.WriteLine("Started");
Console.ReadLine();
appShutdownService.RequestShutdown();
});
shutdownHandle.WaitOne();
}
}
}
这段代码就很好的说明了“entry point”的概念,当我们使用 Self-Host 方式,Microsoft.AspNet.Hosting 就是与我们应用程序的一个入口,用来管理 OWIN 所有组件与应用程序的交互,启动方式使用 K Commands,Host 除了采用 Self-Host 的方式,我们还可以使用 IIS,那他们之间有什么不懂呢?看段配置代码就明白了:
{
"webroot": "wwwroot",
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0-beta1"
}
}
对,你没看错,如果采用 IIS 部署的方式,这就是 project.json 的配置代码,只需要加载一个 Microsoft.AspNet.Server.IIS 程序包就可以了,那这个东西具体有什么作用呢?我们来看一段说明:Using the standard HttpModule and HttpHandler types, OWIN pipelines can run on IIS as a part of an ASP.NET request flow. 我们再来看一下它和 Microsoft.AspNet.Server.WebListener 的不同之处:

一图胜千言,Microsoft.AspNet.Server.IIS 依赖项中的 Microsoft.AspNet.Loader.IIS 是什么东西?其实就是 /wwwroot/bin 目录下的 AspNet.Loader.dll,这个东西在之前的博文中有提到,你可以把它看成是打开 IIS 与 OWIN 管道的一个“开关”,让应用程序的请求放在 IIS 模块进行处理,比如 OWIN 中的某一个 Microsoft.AspNet.StaticFiles Middleware 中间件,对应于 IIS 中的 StaticFilesModule 模块,在应用程序中,关于静态文件的一些请求处理,就是 StaticFilesModule 进行处理的,这是 IIS 的工作范畴。
Server
Server: While the host is responsible for starting and maintaining process within which the application runs, the responsibility of the server is to open a network socket, listen for requests, and send them through the pipeline of OWIN components specified by the user (as you may have already noticed, this pipeline is specified in the application developer’s Startup class).
Host 是管理 OWIN 组件的一个进程,而 Server 则是监听请求,并分发请求给对应的 Middleware 中间件进行处理(Startup 中指定),也就是说 Server 只负责监听与分发,不负责处理,这个就和 IIS 有很明显的区别,IIS 是“全套服务”,请求的处理也在 IIS 中进行完成的,而 Microsoft.AspNet.Server.WebListener 只是完成简单的监听与分发(也可以称为绑定 OWIN 组件)。
目前 OWIN 实现的两个 Server:
- Microsoft.AspNet.Server.WebListener
- Microsoft.AspNet.Server.IIS
说深入理解,其实也只是表面而已,就记录到这。
其他相关资料:
- 快刀斩乱麻之 Katana
- An Overview of Project Katana
- Getting Started with OWIN and Katana
- Understanding OWIN and Katana
- ASP.NET 5中的那些K
- K, KVM, KPM, KLR, KRE in ASP.NET 5 (vNext)
- .NET应用服务器
- OWIN 中 K Commands(OwinHost.exe)与 Microsoft.AspNet.Hosting 的角色问题
深入理解 OWIN 中的 Host 和 Server的更多相关文章
- OWIN的理解和实践(二) – Host和Server的开发
对于开发人员来说,代码就是最好的文档,如上一篇博文所说,下面我们就会基于Kanata项目的一些具体调用代码,来进一步深入理解OWIN的实现和作用. 今天我们先针对Host和Server来实现一个简单的 ...
- OWIN 中 K Commands(OwinHost.exe)与 Microsoft.AspNet.Hosting 的角色问题
问题详情:K Commands(OwinHost.exe)是不是 OWIN 中的 Host 角色?如果是,那 Microsoft.AspNet.Hosting 对应的是 OWIN 中的哪个角色? OW ...
- Host和Server的开发
Host和Server的开发 对于开发人员来说,代码就是最好的文档,如上一篇博文所说,下面我们就会基于Kanata项目的一些具体调用代码,来进一步深入理解OWIN的实现和作用. 今天我们先针对Host ...
- OWIN 中 K Commands 与 OwinHost.exe 相等吗?
OwinHost.exe: While some will want to write a custom process to run Katana Web applications, many wo ...
- 如何理解T-SQL中Merge语句
写在前面的话:之前看过Merge语句,感觉没什么用,完全可以用其他的方式来替代,最近又看了看Merge语句,确实挺好用,可以少写很多代码,看起来也很紧凑,当然也有别的优点. ====正文开始===== ...
- 深入理解Loadrunner中的Browser Emulation
深入理解Loadrunner中的Browser Emulation 深入理解Loadrunner中的Browser Emulation 3E?']V'VgB5n*S0一:基本介绍51Testing软件 ...
- golang中设置Host Header的小Tips
前言 笔者最近时间一直在学习和写Ruby和Go,尤其是Go,作为云计算时代的标准语言,写起来还是相当有感觉的,难过其会越来越火. 不过写的过程中,也遇到了一些小问题,本文就是分享关于go语言设置 HT ...
- 转:理解 PHP 中的 Streams
本文转自:开源中国社区 [http://www.oschina.net]本文标题:理解 PHP 中的 Streams 本文地址:http://www.oschina.net/translate/und ...
- 理解oracle中连接和会话
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp44 理解oracle中连接和会话 1. 概念不同:概念不同: 连接是指物 ...
随机推荐
- webform 分页
界面: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx ...
- cxf3.1.4所需jar,大部分都可以从cxf3.1.4的lib包下找到
asm-.jar commons-beanutils-.jar commons-collections-.jar commons-lang-2.6.jar cxf-core-.jar cxf-rt-b ...
- Repeater的分页
Repeater控件是个好东西.轻量级.又好用.完全的自定义.但是,正是因为这些优点它没有自动分页的功能.这个需要研究一下.我看了一下起点等小说网站,那些什么推荐排名榜用Repeater控件那是很 ...
- perl 切换 dnspod 域名记录
提供域名,dnspod 账户密码(毕竟dns密码比较重要 不能谁 cat一下都可以看到 需要base64加密),原IP,切换目标IP, #!/bin/perl use warnings; use MI ...
- 框架设计之ADO.NET Command的ExecuteScalar误用情景及底层解说
最近下载了点资料,学了学Android,发现Android入门还算简单,从.NET过渡到Android,也就三七十一天的事. 大伙有空也可以学学... 好了,言归正文,那日,有网友发了一个他们公司的数 ...
- BrnShop mvc3升级mvc4
此文来自:http://www.cnblogs.com/fumj/p/3588517.html 手工升级ASP.NET MVC 3项目: 一.安装ASP.NET MVC 4 二.升级ASP.NET M ...
- Linux环境下部署完JDK后运行一个简单的Java程序
前言 前一篇文章详细讲解了如何在Windows环境下安装虚拟机+Linux系统,并且成功部署了JDK. 不过部署完JDK之后,我们判断部署是否成功的依据是看"java -version&qu ...
- [ASP.NET MVC 大牛之路]01 - 开篇
匆匆2014,转眼就到末尾了.在这一年,你还有哪事情些想做而没有做? 2014年在我身上发生了两件意义重大的事,一是正月初一宝宝出生,我升级成为了爸爸:二是进入了一家创业公司,成为了技术负责人. 去年 ...
- struts tags
HTTP ERROR 500 Problem accessing /showognl.jsp. Reason: Server Error Caused by: org.apache.jasper.Ja ...
- JavaWeb配置外部应用的两种方式
原来我们的项目放到webapps下,现在放到外面,也希望tomcat可以找到它!把应用放到tomcat之外,这就是外部应用了.应用已经不在tomcat中了,这时我们需要在tomcat中配置外部应用的位 ...