4

我正在尝试在我的 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) {
        ...
    }

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

4

1 回答 1

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.
于 2014-12-12T07:21:02.217 回答