后来cu的flw告诉说POE的job_server更为简单明了,于是看了看,简单的翻译了一下
一个简单的任务管理器,他允许多个客户端在服务器上同时运行任务,客户端的输入被送到服务端运行。
#!/usr/bin/perl
# http://poe.perl.org/?POE_Cookbook/Job_Server
use warnings;
use strict;
# Include POE, POE::Component::Server::TCP, and POE::Wheel::Run.
#从POE load如下对象
use POE qw(Component::Server::TCP Wheel::Run);
# The programs that are allowed to run, with their names.
# 下面这些是允许发送运行的程序
my %programs = (
time => "/bin/date",
uptime => "/usr/bin/uptime",
ls => "/bin/ls /var/games/*",
echo => "/bin/cat -",
);
# Start a TCP server. The client will be presented with a list of
# valid commands. They can enter one command: that will execute, and
# its output will be sent back to the client. Then the server will
# close the connection.
# 打开一个tcp服务。客户端会看到一系列命令提示,此时键入一个命令,服务器便会执行
#这个命令,并将输出返回给客户端,之后服务器关闭连接。
POE::Component::Server::TCP->new(
Alias => "job_server",
Port => 32080,
# Send the client a list of available commands when it connects.
# 连接时给客户端发送可用命令列表,这些状态都是内置的,我们可以状态设定回调函数
ClientConnected => sub {
$_[KERNEL]->yield("usage");
# yield函数在POE中使用在当前session唤起一个操作时,如果要将一个操作传递到令一个session,使用post
},
# Make sure the job is destroyed when the client exits.
# 确保客户退出时销毁任务
ClientDisconnected => sub {
delete $_[HEAP]->{job};
},
# Process client input. When no job is running, accept input and
# try to spawn a new one. While a job is running, however, pass
# the client's input to it.
#处理客户端的输入。当服务端没有运行任何任务时,客户端接收命令输入并产生一个新的任务,当有任务运行时,把客户端的输入传递过去。
ClientInput => sub {
my ( $heap, $input ) = @_[ HEAP, ARG0 ];
#POE为内置了一系列参数,如:@_[KERNEL,HEAP,ARGO..$#,SESSION]
#heap是用来存储一个session私有数据的地方
if ( $heap->{job} ) {
$heap->{job}->put($input);
return;
}
my $program = $programs{$input};
unless ( defined $program ) {
$_[KERNEL]->yield("usage");
return;
}
$heap->{job} = POE::Wheel::Run->new(
Program => $program,
StdioFilter => POE::Filter::Line->new(),
StderrFilter => POE::Filter::Line->new(),
StdoutEvent => "got_job_stdout",
StderrEvent => "got_job_stderr",
CloseEvent => "got_job_close",
);
$heap->{client}->put( "Job " . $heap->{job}->PID . " started." );
},
# Inline states are custom event handlers. These add handlers for
# job output, job status, and a convenient usage message.
# Inline状态是定制的事件处理器。在这里添加了任务输出,任务状态和方便的使用说明
InlineStates => {
got_job_stdout => sub {
$_[HEAP]->{client}->put("out: $_[ARG0]");
},
got_job_stderr => sub {
$_[HEAP]->{client}->put("ERR: $_[ARG0]");
},
got_job_close => sub {
my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
my $job = delete $heap->{job};
$heap->{client}->put( "Job " . $job->PID . " stopped." );
},
usage => sub {
my @commands = sort keys %programs;
$_[HEAP]->{client}->put("Commands: @commands");
},
},
);
# Run the server until it's done.
$poe_kernel->run();
