Tôi đang phát xung quanh với Mojolicious và websockets. Tôi muốn gửi đầu ra của nhiều lệnh bên ngoài trên máy chủ đến trang web. Tôi không gặp vấn đề gì với việc kết nối và nhận tin nhắn, nhưng tôi cũng muốn gửi một tin nhắn trở lại máy chủ để dừng một lệnh bên ngoài trong khi cho phép người khác tiếp tục gửi tin nhắn lại cho khách hàng. Tôi cũng muốn dừng kiểm tra lệnh bên ngoài khi nó thoát.Tắt sự kiện định kỳ Mojo :: IOLoop được kết nối với Mojo websocket
Lệnh bên ngoài chỉ đơn giản là một lớp lót phun ra một số nguyên sau mỗi vài giây. Tôi có hai websockets hiển thị các số trong riêng biệt div
s. Nhấp vào một trong các nút dừng gửi thông báo, nhưng đó là nơi tôi cần tìm ra cách tắt websocket đó (và chỉ websocket đó) và tắt lệnh bên ngoài.
Khi tôi kết nối các WebSocket, tôi chạy lệnh bên ngoài và thiết lập một Mojo::IOLoop->recurring
để kiểm tra nếu có đầu ra.
Khi tôi muốn dừng lại, tôi cho rằng tôi nên gọi Mojo::IOLoop->remove($id)
, nhưng điều đó dường như không xóa hoàn toàn và tôi nhận được thông báo lỗi như Mojo::Reactor::Poll: Timer failed: Can't call method "is_websocket" on an undefined value
.
Nếu tôi gọi finish
trên đối tượng bộ điều khiển để tắt websocket, có vẻ như sẽ dừng mọi thứ.
Tôi có toàn bộ Mojolicious::Lite app as a gist, nhưng đây là những phần mà tôi
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;
}
câu hỏi khác có thể được hưởng lợi từ câu trả lời này:
Mojolicious có bật khai báo đối số phụ kiểu Perl6 không? – Zaid
Perl v5.20 có chữ ký con là một tính năng thử nghiệm: http: //www.effectiveperlprogramming.com/2015/04/use-v5-20-subroutine-signatures/ –