gri6507 has asked for the wisdom of the Perl Monks concerning the following question:
I am creating a Mojolicious based webapp which uses a websocket connection to periodically serve up JSON data to the client browser, which in turn uses JavaScript to render that JSON data on the webpage. My implementation assumes the following sequence of operation:
Here is the minimal set of code showing the problem.
use warnings; use strict; use Mojolicious::Lite; use Mojo::IOLoop; # Define which template is rendered when the client goes to the base U +RLs. get '/' => 'deleteme'; # WebSocket reading device objects websocket '/ws' => sub { my $self = shift; # Opened $self->app->log->debug('WebSocket opened.'); # Increase inactivity timeout for connection a bit my $loop = Mojo::IOLoop->singleton; $loop->stream($self->tx->connection)->timeout(1000); # Closed $self->on(finish => sub { my ($self, $code, $reason) = @_; $self->app->log->debug("WebSocket closed with status $code."); }); # Incoming message $self->on(message => sub { # safely catch abort signals local $SIG{INT} = $SIG{TERM} = $SIG{__DIE__} = $SIG{__WARN__} += sub { $self->app->log->debug("Safely caught a signal in WebSocke +t message handler"); exit 0; }; }); $self->on(json => sub { my ($self, $hash) = @_; $self->app->log->debug("Got WebSocket JSON request"); # simmulate a handful of iterations of sitting in what otherwi +se would be an infinite loop for my $i (0 .. 10) { my $delay = $loop->delay( # First delay a bit sub { my $theDelay = shift; $loop->timer(5 => $theDelay->begin); $self->app->log->debug("Delay started"); }, # next do the Read and send back the data sub { $self->app->log->debug("Doing periodic useful thin +g"); } ); $delay->wait; exit if ($i > 10); } }); }; app->start;
Here is the required supporting deleteme.html.ep file:
<!DOCTYPE html> <html> <head> <title>Test</title> %= javascript "/jquery-2.0.3.js" %= javascript "/deleteme.js" </head> <body> <center> Status of connection to <label id="connection"><%= url_with('ws')->to_abs %></labe +l> - <label id="status">Disconnected</label> </center><p/> <div id="container"></div> </body> </html>
This uses two JavaScript files. The jQuery.js is the standard source from http://jquery.com/download/. The deleteme.js is below:
$(function () { // figure out where we need to connect to, and then do so var server = $('#connection').text(); var ws = new WebSocket(server); // Figure out where to log the connection status and setup the hoo +ks to log // the current status. Also kick off the initial message to the de +vice var lblStatus = $('#status'); ws.onopen = function () { lblStatus.text('Connected'); ws.send( JSON.stringify({ obj: "AV", num: 1 }) ); }; ws.onclose = function() { lblStatus.text('Disconnected'); }; ws.onerror = function(e) { lblStatus.text('Error: ' + e.data); }; // Parse incoming response and post it to the screen ws.onmessage = function (msg) { var res = JSON.parse(msg.data); if (res.type == "name") { $("<label/>", { 'class': 'objId', 'id' : 'lbl_' + res.obj + '_' + res.num, 'text' : res.obj + res.num }).appendTo('#container'); $("<label/>", { 'class': 'objName', 'id' : 'lblName_' + res.obj + '_' + res.num, 'text' : res.value }).appendTo('#container'); } else { $("<input/>", { 'class' : 'objPv', 'name' : 'inPv_' + res.obj + '_' + res.num, 'type' : 'text', 'value' : res.value }).appendTo('#container'); } }; });
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Mojolicious websocket with server-side repeating events
by gri6507 (Deacon) on Jan 09, 2014 at 21:19 UTC | |
Re: Mojolicious websocket with server-side repeating events
by zentara (Cardinal) on Jan 10, 2014 at 12:03 UTC |