技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 编程语言 --> Plack 代码和结构分析-PSGI Application Architecture[译]

Plack 代码和结构分析-PSGI Application Architecture[译]

浏览:662次  出处信息

PSGI Applications

PSGI spec 中定义了有关 PSGI 的应用相关的内容.

PSGI 应用是一个 Perl 代码块的引用. 它需要一个参数, 环境变量, 并返回一个包含着三个值的数组.

这三个值是 HTTP 的状态 status, 响应的 header, 和 body. 下面是一个简单的例子:

my$app= sub{
    my$env= shift;
    return[
        '200',
        [ 'Content-Type'=> 'text/plain'],
        [ "Hello World"], # or IO::Handle-like object
    ];
};

PSGI 环境变量的哈希

PSGI 环境变量的哈希是一个有很多键的哈希引用. 它主要是这些 (headers, body, etc), 都是从 HTTP::Request 解析并放到这个哈希中来给方便访问.

中间件

中间件会取得 PSGI 的应用, 并运行和传送 PSGI 的环境变量的哈希给它. 它在运行 PSGI 的应用之前, 如果有需要, 它可能会修改环境变量. 并且在运行完应用之后, 它也可能修改响应的内容.

Plack::Middleware

中间件是围绕在 PSGI 的应用上来封装的. 应用可以被一个或者多个中间件包围封装, 这样可以创建一层又一层就象洋葱 onion. 事件驱动和回调让中间件有着不同寻常的结构.

所有的中间件都继承 Plack::Middleware. 它是一个非常小的模块. 这个中间件模块只有 2 个很短的子函数  (注意 call() 和 prepare_app()这二个函数是由使用者来完成):

译注: 现在其实只有一个 wrap 函数了. 其中 to_app 现在是在 Plack::Component 模块中实现. to_app 是用于返回代码块.

subwrap {
    my($self, $app, @args) = @_;
    if(ref$self) {
        $self->{app} = $app;
    } else{
        $self= $self->new({ app => $app, @args});
    }
    return$self->to_app;
}
  
subto_app {
    my$self= shift;
    $self->prepare_app;
    returnsub{ $self->call(@_) };
}

这些函数是怎么样在一起工作的? 这些中间件的洋葱结构决定了, 可以这样构造:

my$app= MyWebApp->new->to_app;
$app= Plack::Middleware::A->wrap($app);
$app= Plack::Middleware::B->wrap($app);
$app= Plack::Middleware::C->wrap($app);

象下面这样写, 可能更加清楚和容易让你明白

my$app0= MyWebApp->new->to_app;           # $app0->($env) 运行 web app
$app1= Plack::Middleware::A->wrap($app0);  # $app1->($env) 调用 P::M::A->call() 这是 $app0->($env)
$app2= Plack::Middleware::B->wrap($app1);  # $app2->($env) 调用 P::M::B->call() 这是 $app1->($env)
$app3= Plack::Middleware::C->wrap($app2);  # $app3->($env) 调用 P::M::C->call() 这是 $app2->($env)
                                            # 当服务器收到一个请求时调用 $app3->($env)

当有新的事件发生时 - 例如, PSGI 的服务器收到一个新的请求 — 它传送这个事件给应用 app. 这个 app 是链式回调来运行每个. 这显然就是事件驱动编程的例子.

Plack::Component 和 Plack::App

Plack::Middleware 继承自 Plack::Component.所以中间件也是使用了 Plack::Component 中的东西.

Plack::Component 是用于创建 PSGI 应用的工具. 它也是很轻量一层的代码, 它主要是用于 Plack::App 名字空间的一些模块实现用的接口. Plack::App::File 是一个 Web 服务器, 用于实现指定目录的静态文件输出,Plack::App::URLMap 是用于给多个 url 指向不同的应用.  

但注意, 我们并不需要在我们的 PSGI 的应用中来指定来 use Plack::Component .  一个 PSGI 的应用只是一个代码块的引用. 这个 PSGI spec 没有讲 PSGI 的应用需要继承 Plack::Component.

我们使用 Plack::Component 提供的接口来在自己创建的应用中使用这些接口. 当我们见到 $app 时, 我们就可以使用这些行为, 这显然看起来就象中间件, 但从设计的角度来讲, 分离开来比较好.

不过这个东西不是在我们的应用中必须的, 它会增加我们的复杂性.

建议继续学习:

  1. Plack 代码和结构分析一[译]    (阅读:993)
  2. Plack 代码和结构分析-Plack::Builder[译]    (阅读:673)
  3. Plack 代码和结构分析-plackup Architecture[译]    (阅读:638)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
  • 作者:扶 凯    来源: 扶凯
  • 标签: Plack
  • 发布时间:2015-02-26 22:29:04
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1