关于OWIN管道

时间:2013-09-19 18:17:46

标签: asp.net owin katana

我有一个关于OWIN管道的简单问题。我非常了解这个规范的整个概念,但有些东西我还没有完全消解。

根据几个在线帖子,有一些OWIN管道,它由几个开发人员定义的模块(或中间件组件)组成,由owin Host构建。然后有服务器将监听请求并通过OWIN组件的管道传递它们。

我不完全理解的一点是,为什么我们需要一个管道。例如,让我们想象一下,在StartUp类中我们有类似的东西:

public class Startup
{
   public void Configuration(IAppBuilder app)
   {
      app.Use<CustomMiddleware>(new CustomComponent());
      var config = new HubConfiguration { EnableCrossDomain = true };
      app.MapHubs(config);
      string exeFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
      string webFolder = Path.Combine(exeFolder, "Web");
      app.UseStaticFiles(webFolder);
   }
}

在上面的例子中,我们要求OWIN主机构建一个包含三个OWIN中间件组件的管道。根据我的理解,服务器会将请求(可能包含在Dictionary中)转发到该管道中的第一个组件,然后该组件将完成一些任务并将其传递给下一个组件,依此类推。

我想知道为什么我们需要获得每个请求中涉及的所有组件;例如,如果我们只要求静态html页面,为什么不打扰处理静态文件的组件;我的意思是为什么这样的请求需要Web Api的参与。

3 个答案:

答案 0 :(得分:3)

我想我已经清除了这一点。事实证明,请求不必遍历整个管道。管道中的每个组件都有责任决定是否可以处理请求,或者是否要将其转发到下一个节点;

答案 1 :(得分:2)

您的回答是正确的,中间件可能会选择不处理请求。许多Katana中间件实现都支持软件404&#34;中间件将404解释为&#34;尝试next中间件&#34;的方法。完成Task的第一个中间件将停止进一步传播并完成响应消息。您可以通过以最可能的顺序插入中间件来优化路径,以实现性能或常用。

答案 2 :(得分:1)

中间件组件按顺序执行,通常运行管道中的所有组件是有意义的,直到其中一个组件决定通过不调用下一个组件来切断管道。

这是可能的,因为每个中间件组件都引用了下一个,the environment是一个对象字典,其键是一个字符串,可以访问所有必要的东西以检查请求,创建响应,并做许多其他事情。 (使用字典很聪明,因为它很容易添加任何类型的信息或可执行代码,事先并不知道。)

每个组件都可以执行以下操作,但所有组件都是可选的:

  • 在调用下一个组件之前执行代码(通常是检查和修改环境字典)
  • 调用管道的下一个中间件组件(将执行相同的操作)
  • 在下一个组件完成执行后执行一些代码
  • 抛出异常(故意或由于未处理的错误)

管道执行将在以下某种情况下完成:

  • 中间件组件不会调用下一个
  • 中间件组件抛出异常

注意:每个&#34;中间件组件&#34;是Application Delegate

的实现

如果他们以正确的顺序注册,那么拥有一堆组件是有道理的。管道可能看起来像这样:

  • 验证
  • 授权
  • 缓存
  • 执行某种API或HTML生成

每个组件都有足够的信息来执行其负责的代码。例如:

  • 认证将被执行,并在字典中设置主体的信息。然后它将下一个:授权组件
  • 根据请求和authenticacion的结果,授权组件将决定主体是否具有执行请求的权限,并调用下一个组件(缓存),或拒绝请求
  • 缓存还可以决定是否可以返回缓存结果,还是必须调用下一个组件
  • 最后一个组件将执行,并且可能会创建响应,并且不会调用任何其他组件。调用堆栈将以相反的顺序运行,为每个组件提供执行某些工作的可能性。例如,缓存组件可以缓存响应,下一个(授权和身份验证)将只返回而不执行任何额外的代码。

由于每个组件都包含所有请求,响应,上下文和任何其他所需信息,因此它们都有足够的信息来决定是否必须执行某些操作,修改dictonay,下一个组件或重新调整...

因此,正如您所看到的,注册许多中间件组件并不需要为每个请求执行所有这些组件,但它有时是有意义的。

OTOH执行中间件组件可能非常便宜。例如,如果请求不需要授权,则身份验证可以简单地执行下一个组件。与cahing组件相同,如果不需要缓存,则可以简单地调用下一个组件。

因此,即使它在管道中的组件可以具有廉价的执行,或者根据请求它甚至根本不能运行。

在您的静态文件和Web API的特定问题中,其中一个组件将在另一个组件之前被撤销。第一个,无论哪个,都将执行并创建响应,或者只是调用下一个响应,具体取决于请求。例如。如果静态文件在另一个之前注册,如果请求文件,静态文件将创建响应,并且不会调用Web API。如果请求不是文件的请求,除了调用下一个组件之外什么也不做:Web API组件。