使用AnyEvent(Perl)创建单线程服务器
我正在创建一个本地服务来监听localhost,并提供一个基本的调用和响应类型接口。我想首先介绍一个婴儿服务器,您可以通过telnet连接到该服务器,并响应它接收到的内容 我听说AnyEvent在这方面很好,但是AnyEvent::Socket的文档并没有给出一个很好的示例。我想用AnyEvent、AnyEvent::Socket和AnyEvent::Handle构建它 现在,小服务器代码如下所示:使用AnyEvent(Perl)创建单线程服务器,perl,webserver,anyevent,Perl,Webserver,Anyevent,我正在创建一个本地服务来监听localhost,并提供一个基本的调用和响应类型接口。我想首先介绍一个婴儿服务器,您可以通过telnet连接到该服务器,并响应它接收到的内容 我听说AnyEvent在这方面很好,但是AnyEvent::Socket的文档并没有给出一个很好的示例。我想用AnyEvent、AnyEvent::Socket和AnyEvent::Handle构建它 现在,小服务器代码如下所示: #!/usr/bin/env perl use AnyEvent; use AnyEvent:
#!/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;
这不起作用,而且如果我将telnet连接到localhost:44244,我会得到以下结果:
EV: error in callback (ignoring): AnyEvent::CondVar:
recursive blocking wait attempted at server.pl line 29.
我想,如果我知道如何制作一个小型的单线程服务器,我可以通过telnet连接到它,打印出它给出的任何内容,然后等待更多的输入,那么我可以将它做得更远。有什么想法吗?我不确定你的condvar试图触发什么。使用它发送状态,如:
#!/usr/bin/env perl
use AnyEvent;
use AnyEvent::Handle;
use AnyEvent::Socket;
my $host = '127.0.0.1';
my $port = 44244;
my $exit = AnyEvent->condvar;
tcp_server($host, $port, sub {
my($fh) = @_;
my $handle; $handle = AnyEvent::Handle->new(
fh => $fh,
poll => "r",
on_read => sub {
my($self) = @_;
print "Received: " . $self->rbuf . "\n";
if ($self->rbuf eq 'exit') {
$exit->send;
}
}
);
});
print "Listening on $host\n";
$exit->recv;
我也听到过关于任何事件的好消息,但没有使用它。过去,我使用IO::Select编写了一个小型非阻塞服务器。在中有一个例子,我添加了几行:
use IO::Select;
use IO::Socket;
$lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
$sel = new IO::Select( $lsn );
while(@ready = $sel->can_read) {
foreach $fh (@ready) {
if($fh == $lsn) {
# Create a new socket
$new = $lsn->accept;
$sel->add($new);
}
else {
# Process socket
my $input = <$fh>;
print $fh "Hello there. You said: $input\n";
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;
}
}
}
你在回叫中阻塞了。这是不允许的。有几种方法可以解决这个问题。我的首选是从tcp_服务器回调中启动线程。但如果没有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;
请注意,我只等待一个条件。我正在存储句柄,以使AnyEvent::Handle对象保持更长的活动时间。清理$self->rbuf的工作留给读者作为练习:-
交叉发布的问题:-交叉发布在。当我在telnet上尝试此操作时,我得到以下结果:$telnet localhost 44244 Trying 127.0.0.1。。。已连接到本地主机。转义字符为“^]”。连接被外部主机关闭。无论如何,让它阅读,打印,然后等待另一个?太棒了,谢谢:-嘿,问题,你如何将数据发送回客户?打印到$fh?@DavidWilliams-不,这将阻止。请参阅文档,它位于synoposis:$hdl->push_write。