Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

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: ./ 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="// +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" +; }; % 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

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

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2021-06-22 10:27 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (102 votes). Check out past polls.