I am new to web sockets and I am creating a web GUI around a command line interface that talks to IoT devices. Some commands take a few seconds because I am sending them to a large network of devices.
It would be very useful if I could send the responses of individual devices to a text area (resembling a terminal window) as responses arrive.
I am using a web socket connection between client and server. Here is a simplified example of the effect I'm trying to achieve.
use strict;
use warnings;
use Mojolicious::Lite;
get '/' => 'index';
websocket '/get_loop' => sub {
my $c = shift;
$c->app->log->debug("Websocket opened");
$c->on(message => sub {
my ($c, $msg) = @_;
for (my $i = 0; $i < 10; $i++) {
$c->send("$i\n");
$c->app->log->debug("$i\n");
sleep (1);
};
});
$c->on(finish => sub {
my ($c, $code, $reason) = @_;
$c->app->log->debug("WebSocket closed with status $code");
});
};
app->start;
__DATA__
@@ index.html.ep
<html>
<head>
<title>Websocket Test</title>
<style type="text/css">
textarea {
height: 200px;
width: 100px;
}
</style>
</head>
<body>
<h1>Websocket Test</h1>
<textarea id="terminal" readonly></textarea>
<script type="text/javascript">
var ws = new WebSocket('ws://127.0.0.1:3000/get_loop');
var terminal = document.getElementById('terminal');
ws.onopen = function() {
ws.send('start');
};
ws.onmessage = function(event) {
var msg = event.data;
terminal.innerHTML += msg;
};
</script>
</body>
</html>
0 14. - , . CLI . -?
-Edit -
- Mojo::IOLoop->recurring , .
websocket '/get_loop' => sub {
my $c = shift;
$c->app->log->debug("Websocket opened");
my $id;
$c->on(message => sub {
my ($c, $msg) = @_;
my $count = 0;
$id = Mojo::IOLoop->recurring(1 => sub {
$c->send("$count\n");
$c->app->log->debug($count);
sleep (1);
$c->finish if $count++ == 10;
});
});
$c->on(finish => sub {
my ($c, $code, $reason) = @_;
Mojo::IOLoop->remove($id);
$c->app->log->debug("WebSocket closed with status $code");
});
};