Plack 代码和结构分析-PSGI Application Architecture[译]
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 时, 我们就可以使用这些行为, 这显然看起来就象中间件, 但从设计的角度来讲, 分离开来比较好.
不过这个东西不是在我们的应用中必须的, 它会增加我们的复杂性.
建议继续学习:
- Plack 代码和结构分析一[译] (阅读:1583)
- Plack 代码和结构分析-Plack::Builder[译] (阅读:1424)
- Plack 代码和结构分析-plackup Architecture[译] (阅读:1166)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:扶 凯 来源: 扶凯
- 标签: Plack
- 发布时间:2015-02-26 22:29:04
-
[930] WordPress插件开发 -- 在插件使用 -
[130] 解决 nginx 反向代理网页首尾出现神秘字 -
[51] 如何保证一个程序在单台服务器上只有唯一实例( -
[51] 海量小文件存储 -
[50] 整理了一份招PHP高级工程师的面试题 -
[49] CloudSMS:免费匿名的云短信 -
[48] 全站换域名时利用nginx和javascri -
[48] 用 Jquery 模拟 select -
[47] Innodb分表太多或者表分区太多,会导致内 -
[46] ps 命令常见用法
