gpt4 book ai didi

perl - 关闭连接到 Mojo websocket 的 Mojo::IOLoop 重复事件

转载 作者:行者123 更新时间:2023-12-04 08:42:04 30 4
gpt4 key购买 nike

我在玩 Mojolicious 和 websockets。我想将服务器上多个外部命令的输出发送到网页。我在连接和接收消息方面没有问题,但我还想将消息发送回服务器以停止外部命令,同时让其他人继续向客户端发送消息。一旦退出,我也想停止检查外部命令。

外部命令只是一个单行程序,每隔几秒就会输出一个整数。我有两个 websockets 分别显示数字 div s。单击任一停止按钮都会发送消息,但这就是我需要弄清楚如何关闭该 websocket(并且仅该 websocket)并关闭外部命令的地方。

enter image description here

当我连接websocket时,我运行外部命令并设置了一个Mojo::IOLoop->recurring检查是否有输出。

当我想停下来时,我想我应该打电话Mojo::IOLoop->remove($id) ,但这似乎并没有完全删除它,我收到类似 Mojo::Reactor::Poll: Timer failed: Can't call method "is_websocket" on an undefined value 的错误消息.

如果我打电话finish在 Controller 对象上关闭 websocket,它似乎停止了一切。

我有整个 Mojolicious::Lite app as a gist ,但这是我所在的部分

use feature qw(signatures);
no warnings qw(experimental::signatures);
## other boilerplate redacted

websocket '/find' => sub ( $c ) {
state $loop = Mojo::IOLoop->singleton;

app->log->debug( "websocket for find" );
$c->inactivity_timeout( 50 );

my $id;
$c->on( message => sub ( $ws, $message ) {
my $json = decode_json( $message );
my $command = $json->{c};
my $name = $json->{n};

app->log->debug( "Got $command command for $name" );
if( $command eq "start" ) {
$id = run_command( $ws );
app->log->debug( "run_command for $name returned [$id]" );
}
elsif( $command eq "stop" ) {
app->log->debug( "stopping loop for $name [$id]" );
# XXX What should I do here?
# $ws->finish;
# $loop->remove( $id );
}
elsif( $command eq "open" ) {
app->log->debug( "opening websocket for $name" );
}
}
);
$c->on(
finish => sub ( $c, $code ) {
app->log->debug("WebSocket closed with status $code");
}
);
};

app->start;

sub run_command ( $ws ) {
app->log->debug( "In run_command: $ws" );
open my $fh, "$^X -le '\$|++; while(1) { print int rand(100); sleep 3 }' |";
$fh->autoflush;

my $id;
$id = Mojo::IOLoop->recurring( 1 => sub ($loop) {
my $m = <$fh>;
unless( defined $m ) {
app->log->debug( "Closing down recurring loop from the inside [$id]" );
# XXX: what should I do here?
close $fh;
return;
};
chomp $m;
app->log->debug( "Input [$m] for [$id] from $fh" );
$ws->send( encode_json( { 'm' => $m } ) );
});

return $id;
}

可以从这个答案中受益的其他问题:
  • Output command to socket without buffering using Mojo::IOLoop
  • 最佳答案

    我玩了一下。 Logioniz's answer让我觉得我不应该自己轮询或处理文件句柄细节。我仍然不知道它卡在哪里。

    相反,我使用了 Mojo::Reactorio设置要监视的文件句柄:

    sub run_command ( $ws ) {
    my $pid = open my $fh, "$^X -le '\$|++; print \$\$; while(1) { print int rand(100); sleep 3 }' |";
    $fh->autoflush;

    my $reactor = Mojo::IOLoop->singleton->reactor->io(
    $fh => sub ($reactor, $writeable) {
    my $m = <$fh>;
    chomp $m;
    $ws->send( encode_json( { 'm' => $m } ) );
    }
    );

    return ( $fh, $pid );
    }

    完成该命令后,我可以取消监视该文件句柄并终止该进程。我完成了 websocket:
        elsif( $command eq "stop" ) {
    $loop->reactor->watch( $fh, 0, 0 );
    kill 'KILL', $pid or app->log->debug( "Could not kill $pid: $!" );
    $ws->finish;
    }

    我还是不知道为什么 remove($fh)不起作用。我想我这样做是在泄漏一些 IOLoop 的东西。

    关于perl - 关闭连接到 Mojo websocket 的 Mojo::IOLoop 重复事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36673303/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com