本文介绍了使用AnyEvent(Perl)创建单线程服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on creating a local service to listen on localhost and provide a basic call and response type interface. What I'd like to start with is a baby server that you can connect to over telnet and echoes what it receives.

我听说AnyEvent非常适合此操作,但是AnyEvent :: Socket的文档并未给出如何执行此操作的很好示例.我想用AnyEvent,AnyEvent :: Socket和AnyEvent :: Handle构建它.

I've heard AnyEvent is great for this, but the documentation for AnyEvent::Socket does not give a very good example how to do this. I'd like to build this with AnyEvent, AnyEvent::Socket and AnyEvent::Handle.

现在小服务器代码如下:

Right now the little server code looks like this:

#!/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;

这不起作用,如果我远程登录到本地主机:44244,我也会得到:

This doesn't work and also if I telnet to localhost:44244 I get this:

EV: error in callback (ignoring): AnyEvent::CondVar: 
recursive blocking wait attempted at server.pl line 29.

我认为,如果我了解如何制作一个小型单线程服务器,可以通过telnet连接到该服务器,并打印出它所提供的任何内容,然后等待更多的输入,那么我可以做得更多.有什么想法吗?

I think if I understand how to make a small single threaded server that I can connect to over telnet and prints out whatever its given and then waits for more input, I could take it a lot further from there. Any ideas?

推荐答案

您正在阻止回调.那是不允许的.有几种方法可以解决此问题.我的偏好是从tcp_server回调中启动 Coro 线程.但是如果没有Coro,您可能正在寻找这样的东西:

You're blocking inside a callback. That's not allowed. There are a few ways to handle this. My preference is to launch a Coro thread from within the tcp_server callback. But without Coro, something like this might be what you're looking for:

#!/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的工作留给读者练习:-)

Note that I'm only waiting on one condvar. And I'm storing the handles to keep the AnyEvent::Handle objects alive longer. Work to clean up the $self->rbuf is left as an excersise for the reader :-)

交叉发布的问题,答案也:-)

Question cross-posted, answer, too :-)

这篇关于使用AnyEvent(Perl)创建单线程服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 17:24