AnyEvent->计时器不能与AnyEvent :: Handle一起使用?

时间:2014-11-03 12:24:32

标签: perl websocket catalyst anyevent

我正在尝试在Catalyst,AnyEvent,Websocket应用程序中构建超时方案。 为此,我正在使用

AnyEvent->timer

应该在让我们说几秒钟不活动之后调用(不再有WS帧进入)。

问题是,我的计时器永远不会被执行:

my $w = AnyEvent->timer (after => 3,
                         cb    => sub {
    warn "TIMEOUT!";
});

$self->{server} = Protocol::WebSocket::Handshake::Server->new_from_psgi(
                            $c->req->env) or die $c->log->fatal($!);

$self->{handle} = AnyEvent::Handle->new(
    fh => $c->req->io_fh,
    on_error => sub {
        my ($hd, $fatal, $msg) = @_;
        $clean_up->();
    }
);

die $c->log->fatal("WS Server error: '$_'")
        if $self->{server}->error;

$self->{server}->parse($self->{handle}->fh);
$self->{handle}->push_write($self->{server}->to_string);

$self->{handle}->on_read(sub {
    (my $frame = $self->{server}->build_frame)->append($_[0]->rbuf);

    while (my $frame_msg = $frame->next) {
        ...
    }

永远不会执行定时器回调。 我的猜测是,计时器在另一个Event循环(AnyEvent :: Handle)中不起作用?

1 个答案:

答案 0 :(得分:3)

您是否真正进入事件循环以处理计时器?您的代码段并未指明此内容。

此外,AnyEvent::Handle内置了非活动超时:

       timeout => $fractional_seconds
           If non-zero, then this enables an "inactivity" timeout: whenever
           this many seconds pass without a successful read or write on the
           underlying file handle, the "on_timeout" callback will be invoked
           (and if that one is missing, a non-fatal "ETIMEDOUT" error will
           be raised).

           Note that timeout processing is also active when you currently do
           not have any outstanding read or write requests: If you plan to
           keep the connection idle then you should disable the timout
           temporarily or ignore the timeout in the "on_timeout" callback,
           in which case AnyEvent::Handle will simply restart the timeout.

           Zero (the default) disables this timeout.

       on_timeout => $cb->($handle)
           Called whenever the inactivity timeout passes. If you return from
           this callback, then the timeout will be reset as if some activity
           had happened, so this condition is not fatal in any way.