首页 文章

关于OWIN管道

提问于
浏览
3

我有一个关于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 回答

  • 1

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

  • 2

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

  • 3

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

    这是可能的,因为每个中间件组件都有对下一个的引用,而the environment是一个对象的字典,其键是一个字符串,可以访问所有必要的东西来检查请求,创建响应,以及执行许多其他操作 . 的东西 . (使用字典很聪明,因为它事先已知) .

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

    • 在调用下一个组件之前执行代码(通常检查和修改环境字典)

    • 调用管道的下一个中间件组件(将执行相同的操作)

    • 在下一个组件完成执行后执行一些代码

    • 抛出异常(故意或因未处理的错误)

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

    • 中间件组件不会调用下一个

    • 中间件组件抛出异常

    注意:每个"Middleware component"都是Application Delegate的实现

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

    • 认证

    • 授权

    • 缓存

    • 执行某种API或HTML生成

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

    • 认证将被执行,并在字典中设置主体的信息 . 然后它将下一个:授权组件

    • 取决于请求和authenticacion的结果,授权组件将决定主体是否具有执行请求的权限,并调用下一个组件(缓存),或拒绝请求

    • 缓存还可以决定它是否可以返回缓存结果,还是必须调用下一个组件

    • 最后一个组件将执行,并且可能会创建响应,并且它不会调用任何其他组件 . 调用堆栈将以相反的顺序运行,为每个组件提供执行某些工作的可能性 . 例如,缓存组件可以缓存响应,下一个(授权和身份验证)将只返回而不执行任何额外的代码 .

    由于每个组件都有所有请求,响应,上下文和任何其他所需的信息,他们都有足够的信息来决定他们是否必须做某事,修改dictonay,下一个或者重新调整...

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

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

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

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

相关问题