Hello all.

I am building a web app that will run compliance checks on client-submitted files placed in a special directory. These checks can run for more than a minute, and I want the output from those checks to be displayed in the web browser as they are generated...not waiting to the end of the run. The non-blocking Mojolicious server and WebSockets seem like a good solution technique.

In the following code, &myapp() simulates the long running checks, occasionally producing output. The good news is the desired output appears in the web browser, that output being "Connection open. Entering log4. Entering myapp. 0... 1... 2... 3... Leaving myapp. Leaving log4." The problem is the web browser sits idle for 12 seconds, and then the output displays all at once. Instead, I would like the output to appear in the web browser as soon as $tx->send() is called. How can that be accomplished with Mojolicious?

Tcpdump shows the web server is sending the output all at once, not as $tx->send() is called.

Here is the complete, running code (in one file):

#!/usr/bin/perl ## run as: ./wbsckt.pl daemon use Mojolicious::Lite; ## Automatically enables "strict", "warnings", "utf8" and Perl 5.10 fe +atures; &startup; ##------------------------------------------------------------------- sub myapp{ my $tx=shift; $tx->send("Entering myapp."); foreach my $xx (0..3) { $tx->send("$xx..."); sleep(3); } $tx->send("Leaving myapp."); return "You should never see this."; } ##------------------------------------------------------------------- sub startup{ get '/' => sub { my $c=shift; $c->render('index'); }; get '/log2' => sub { my $c=shift; $c->render('log2'); }; websocket '/log3' => \&ws_log4; app->secrets(['password' => '8675309J']); app->start; } ##------------------------------------------------------------------- sub ws_log4{ my $self= shift; my $tx= $self->tx; my $ip= $tx->remote_address; app->log->debug("Client '$ip' connected"); $tx->send("Entering log4."); $self->on(&myapp($tx) => sub { my($ws,$msg)= @_; $ws->inactivity_timeout(50); $ws->send("Time is: " . scalar(localtime())); ## odd, we neve +r see this output }); $self->on(finish => sub { my($c,$code,$reason)= @_; $c->app->log->debug("WebSocket closed with status $code."); }); $tx->send("Leaving log4."); } ##------------------------------------------------------------------- __DATA__ @@ index.html.ep <!DOCTYPE html> <html> <head><title>Static Page</title> </head> <body> <h1>Index Page</h1> <p>This is a static page. For WebSockets example, click <a href="/log2">here</a>. </p> </body> </html> @@ log2.html.ep <!DOCTYPE html> <html> <head> <title>WebSockets Example</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min. +js"></script> </head> <body> <p id="result"></p> %= javascript begin var ws = new WebSocket('<%= url_for('log3')->to_abs %>'); ws.onopen = function() { $('#result').text("Connection open."); //ws.send("Hi."); }; ws.onmessage = function (e) { $('#result').append( "\n" + e.data); }; % end </body> </html>

This code is running on CentOS 6.5, Perl 5.10.1 with these perl modules: EV 4.18; IO::Socket::Sockets 0.65; IO::Socket::SSL 2.007.

Thank you very much for your insight and patience.


In reply to real-time output from Mojolicious WebSockets? by BroFish

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.