Dav*_*ams 4 perl webserver anyevent
我正在创建一个本地服务来监听localhost并提供一个基本的调用和响应类型接口.我想要开始的是一个婴儿服务器,您可以通过telnet连接并回应它收到的内容.
我听说AnyEvent对此非常有用,但是AnyEvent :: Socket的文档并没有给出一个很好的例子.我想用AnyEvent,AnyEvent :: Socket和AnyEvent :: Handle构建它.
现在,小服务器代码如下所示:
#!/usr/bin/env perl
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
my $cv = AnyEvent->condvar;
my $host = '127.0.0.1';
my $port = 44244;
tcp_server($host, $port, sub {
my($fh) = @_;
my $cv = AnyEvent->condvar;
my $handle;
$handle = AnyEvent::Handle->new(
fh => $fh,
poll => "r",
on_read => sub {
my($self) = @_;
print "Received: " . $self->rbuf . "\n";
$cv->send;
}
);
$cv->recv;
});
print "Listening on $host\n";
$cv->wait;
Run Code Online (Sandbox Code Playgroud)
这不起作用,如果我telnet到localhost:44244我得到这个:
EV: error in callback (ignoring): AnyEvent::CondVar:
recursive blocking wait attempted at server.pl line 29.
Run Code Online (Sandbox Code Playgroud)
我想如果我理解如何创建一个小的单线程服务器,我可以通过telnet连接并打印出它给出的任何内容,然后等待更多输入,我可以从那里进一步采取它.有任何想法吗?
你在回调中阻止了.这是不允许的.有几种方法可以解决这个问题.我的偏好是从tcp_server回调中启动一个Coro线程.但是如果没有Coro,这样的事情可能就是你想要的:
#!/usr/bin/env perl5.16.2
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
my $cv = AE::cv;
my $host = '127.0.0.1';
my $port = 44244;
my %connections;
tcp_server(
$host, $port, sub {
my ($fh) = @_;
print "Connected...\n";
my $handle;
$handle = AnyEvent::Handle->new(
fh => $fh,
poll => 'r',
on_read => sub {
my ($self) = @_;
print "Received: " . $self->rbuf . "\n";
},
on_eof => sub {
my ($hdl) = @_;
$hdl->destroy();
},
);
$connections{$handle} = $handle; # keep it alive.
return;
});
print "Listening on $host\n";
$cv->recv;
Run Code Online (Sandbox Code Playgroud)
请注意,我只等待一个condvar.我正在存储句柄以使AnyEvent :: Handle对象保持更长时间.清理$ self-> rbuf的工作留给了读者一个例外:-)
问题交叉发布,答案也是 :-)