Sto giocando con Mojolicious e websockets. Voglio inviare l'output di più comandi esterni sul server alla pagina web. Non ho problemi con la connessione e la ricezione di messaggi, ma desidero anche inviare un messaggio al server per interrompere un comando esterno lasciando che gli altri continuino a inviare messaggi al client. Voglio anche smettere di controllare il comando esterno quando esce.Arresto di un evento Mojo :: IOLoop collegato a una rete Web Mojo
Il comando esterno è semplicemente un one-liner che emette un numero intero ogni pochi secondi. Ho due web socket che visualizzano i numeri in separati div
s. Facendo clic su uno dei pulsanti di arresto viene inviato il messaggio, ma è lì che devo capire come spegnere quel websocket (e solo quel websocket) e chiudere il comando esterno.
quando collego il websocket, corro il comando esterno e creare un Mojo::IOLoop->recurring
per verificare se c'è uscita.
Quando voglio fermarmi, immagino che dovrei chiamare Mojo::IOLoop->remove($id)
, ma questo non sembra rimuoverlo completamente e ricevo messaggi di errore come Mojo::Reactor::Poll: Timer failed: Can't call method "is_websocket" on an undefined value
.
Se chiamo finish
sull'oggetto controller per arrestare il websocket, sembra che tutto si fermi.
devo tutto Mojolicious::Lite app as a gist, ma qui è la parte dove mi
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;
}
Altre questioni che possono beneficiare di questa risposta:
Mojolicious abilita la dichiarazione di sottotitoli in stile Perl6? – Zaid
Perl v5.20 ha firme di subroutine come funzionalità sperimentale: http: //www.effectiveperlprogramming.com/2015/04/use-v5-20-subroutine-signatures/ –