首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用AnyEvent创建单线程服务器(Perl)

使用AnyEvent创建单线程服务器(Perl)
EN

Stack Overflow用户
提问于 2012-11-07 06:59:06
回答 3查看 3.5K关注 0票数 5

我正在创建一个本地服务来监听localhost,并提供一个基本的调用和响应类型接口。我想要开始的是一个婴儿服务器,您可以通过telnet连接到它并回显它接收到的内容。

我听说AnyEvent在这方面做得很好,但是AnyEvent::Socket的文档并没有给出一个很好的例子来说明如何做到这一点。我想用AnyEvent、AnyEvent::Socket和AnyEvent::Handle来构建它。

现在,小服务器代码如下所示:

代码语言:javascript
复制
#!/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,我会得到这个:

代码语言:javascript
复制
EV: error in callback (ignoring): AnyEvent::CondVar: 
recursive blocking wait attempted at server.pl line 29.

我想,如果我知道如何制作一个小的单线程服务器,我可以通过telnet连接到它,并打印出它给出的任何东西,然后等待更多的输入,我可以从那里走得更远。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-07 08:34:23

你在回调中阻塞了。这是不允许的。有几种方法可以处理这个问题。我更喜欢从tcp_server回调中启动一个Coro线程。但是如果没有Coro,这样的东西可能就是你想要的:

代码语言:javascript
复制
#!/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;

请注意,我只等待一个condvar。我正在存储句柄,以使AnyEvent::Handle对象保持更长的存活时间。清理$self->rbuf的工作留给读者作为摘录:-)

问题交叉发布,answer, too :-)

票数 6
EN

Stack Overflow用户

发布于 2012-11-07 08:19:23

我也听说过关于AnyEvent的好东西,但还没有用过。我以前使用IO::Select编写了一个小型的非阻塞服务器。在documentation for that module中有一个示例(我已经添加了几行):

代码语言:javascript
复制
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;
        }
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-11-07 07:14:31

我不确定condvar在那里试图触发什么。使用它来发送状态,例如:

代码语言:javascript
复制
#!/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;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13260802

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档