Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
tail on the browser
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  5 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
marcos rebelo  
View profile  
 More options Apr 20 2012, 10:50 am
From: marcos rebelo <ole...@gmail.com>
Date: Fri, 20 Apr 2012 16:50:47 +0200
Local: Fri, Apr 20 2012 10:50 am
Subject: tail on the browser

Hi all

I'm getting crazy with the next script. The script is a sort of tail for a
file on the server, when I start the server it works ok but when I try to
reload the page doesn't work any more.

What am I doing wrong?

#!/usr/bin/env perl
use Mojolicious::Lite;

get '/' => sub {
  my $self = shift;
  $self->render('index');

};

my $loop = Mojo::IOLoop->singleton;
my $FILE_PATH = __FILE__; # Just for example now

websocket '/tail' => sub {
    my $self = shift;

    open(my $fh, '-|', 'tail', '-f', $FILE_PATH) or die $!;

    $self->on(finish => sub {
        close $fh;
        $fh = undef;
    } );

    my $sub;
    $sub = sub {
        return if not defined $fh;
        my $line = readline($fh);
        $self->send_message( $line );
        print "SEND: $line";
        $loop->timer(0, $sub);
    };

    $sub->();

};

app->start;
__DATA__

@@ index.html.ep
<!DOCTYPE html>
<html>
    <head>
        <title>tail</title>
        <style>
            .class-test {
                width:10000px;
            }
        </style>
        <script type="text/javascript" src="
http://code.jquery.com/jquery-1.7.2.min.js"></script>
        <script>
            "use strict"

            var create_line_div = function( text ) {
                var div = $("<div></div>");
                div.text(text);
                return div;
            };

            var websocket;
            var createWebSocket = function () {
                websocket = new WebSocket("<%=
$self->req->url->to_abs->scheme( $self->req->is_secure ? 'wss' : 'ws'
)->path( '/tail' ) %>");
                websocket.onmessage = function(evt) {
$('.class-test').append( $( create_line_div( evt.data ) ) ) };
            };

            $( createWebSocket() );
        </script>
    </head>
    <body>
        Welcome to Tail!
        <div class='class-test'>
        </div>
    </body>
</html>

Best Regards
Marcos Rebelo

--
Marcos Rebelo
http://www.oleber.com/
Webmaster of http://perl5notebook.oleber.com


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Gabriel Vieira  
View profile  
 More options Apr 20 2012, 11:12 am
From: Gabriel Vieira <gabriel.vie...@gmail.com>
Date: Fri, 20 Apr 2012 12:12:15 -0300
Local: Fri, Apr 20 2012 11:12 am
Subject: Re: [Mojolicious] tail on the browser

CGI?

--
Gabriel Vieira

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
marcos rebelo  
View profile  
 More options Apr 20 2012, 11:37 am
From: marcos rebelo <ole...@gmail.com>
Date: Fri, 20 Apr 2012 17:37:05 +0200
Local: Fri, Apr 20 2012 11:37 am
Subject: Re: [Mojolicious] tail on the browser

morbo script.pl

On Fri, Apr 20, 2012 at 17:12, Gabriel Vieira <gabriel.vie...@gmail.com>wrote:

--
Marcos Rebelo
http://www.oleber.com/
Webmaster of http://perl5notebook.oleber.com

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tobias Oetiker  
View profile  
 More options Apr 20 2012, 11:38 am
From: Tobias Oetiker <t...@oetiker.ch>
Date: Fri, 20 Apr 2012 17:38:56 +0200 (CEST)
Local: Fri, Apr 20 2012 11:38 am
Subject: Re: [Mojolicious] tail on the browser
Hi Marcos,

I have appended code I wrote for the a event-stream client which
might give you some inspiration ...  note that the design is
different as the data source (tail -f) only runs once and not for
every client connecting ... in your design every connection gets
its own tail ....

package Signage2;
use Mojo::Base 'Mojolicious';

# This method will run once at server start
sub startup {
    my $self = shift;
    # Router
    my $r = $self->routes;
    my $log = $self->log;
    $r->get('/' => 'index');
    my $stream = $self->launch_arec;
    my $loop = Mojo::IOLoop->singleton;
    $r->get('/sound' => sub {
        my $self = shift;
        # Change content type
        my $out_stream = $loop->stream($self->tx->connection);
        $self->res->headers->content_type('text/event-stream');
        # stop mojo from complaining about incomplete page
        $self->render_later;
        my $read_cb = $stream->on(read => sub {
            my ($stream, $chunk) = @_;
            while ($chunk =~ m{^(.+)[\r\n]+}g){
                $self->write("event:log\ndata:".$1."\n\n");
            }
        });
        my $close = sub {
            my $stream = shift;
            $self->write("event:log\ndata:Closed\n\n") if $self;
            $log->info("closed client connection");
            $self->finish;
        };
        $stream->once(close => $close);
        $stream->once(error => $close);

        my $unsubscribe = sub {
            $stream->unsubscribe(read=>$read_cb);
            $log->info("browser gone");
        };

        # when the connnection is dead, stop writing to it
        $out_stream->once(timeout => $unsubscribe);
        $out_stream->once(close => $unsubscribe);

    });

}

sub launch_tail {
    my $self = shift;
    # Increase inactivity timeout for connection a bit
    my $log = $self->log;
    my $pid = open(my $fh,"-|", "tail","-f","$FILE_PATH") ||
                die "can't fork: $!";
    # Create stream
    my $loop = Mojo::IOLoop->singleton;
    my $stream = Mojo::IOLoop::Stream->new($fh);
    # register with the io loop
    my $id = $loop->stream($stream);
    $stream->on(error => sub {
         my ($stream, $err) = @_;
         $loop->remove($id);
         $log->error("Stream Error: $err");
    });

    $stream->on(close => sub {
         my $stream = shift;
         $log->info("closing connection to tail");
         waitpid($pid,0);
         $loop->remove($id);
    });
    $stream->start;
    return $stream;

}

1;

--
Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
http://it.oetiker.ch t...@oetiker.ch ++41 62 775 9902 / sb: -9900

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ed W  
View profile  
 More options Apr 20 2012, 1:13 pm
From: Ed W <li...@wildgooses.com>
Date: Fri, 20 Apr 2012 18:13:18 +0100
Local: Fri, Apr 20 2012 1:13 pm
Subject: Re: [Mojolicious] tail on the browser

Hi

> What am I doing wrong?

I think if you add some print statements you will find that you block on
the close $fh ?

>     open(my $fh, '-|', 'tail', '-f', $FILE_PATH) or die $!;
>     $self->on(finish => sub {
>         close $fh;
>         $fh = undef;
>     } );

I haven't tested, but I think the close will wait for tail to finish and
block?

Here is my attempt at a loop - note there are some extreme subtleties
here and I would love for Sebastian to comment on the "correct" way to
handle callbacks.  What you should watch for is that some of the handles
are weakened, and also the various shutdown functions throw ugly warning
if you re-enter them.  So you need to design your closedown so that you
can kill either the tail which kills the web connection, or kill the web
connection which kills the tail, all without creating a loop:

---

get '/system/logs' => 'system/logs';

# EventSource for log messages
get '/system/logs-es' => sub {
   my $self = shift;
   $self->render_later;

   # Increase inactivity timeout for connection a bit
   Mojo::IOLoop->stream( $self->tx->connection )->timeout(300);

   # Change content type
   $self->res->headers->content_type('text/event-stream');
   $self->res->headers->header( 'X-Accel-Buffering' => 'no' );

   my $pid = open( my $fh, "-|", "tail -F -n 0 /var/log/messages" );
   defined($pid) || die "can't fork: $!";

   # Create stream
   my $stream = Mojo::IOLoop::Stream->new($fh);
   $stream->timeout(0);
   $stream->on(
     read => sub {
       my ( $stream, $chunk ) = @_;
       $chunk = $self->txt_to_html($chunk);
       $self->write("event:log\ndata:$chunk\n\n");
     }
   );
   $stream->on(
     close => sub {
       my $stream = shift;
       say "Close";    # DEBUG
       $self->finish("event:log\ndata:Log Closed<br><br>\n\n") if (
$self && $self->tx && !$self->tx->is_finished );
     }
   );
   $stream->on(
     error => sub {
       my ( $stream, $err ) = @_;
       say "MY Error: $err";    # DEBUG
       $self->finish("event:log\ndata:Error...Closing<br><br>\n\n") if (
$self && $self->tx && !$self->tx->is_finished );
     }
   );

   # Start listening to $fh
   Mojo::IOLoop->singleton->stream($stream);

   # Unsubscribe from "message" event again once we are done
   $self->on(
     finish => sub {
       my $self = shift;
       say "Finishing";         # DEBUG
#    Mojo::IOLoop->singleton->drop($fh);
#    $stream->close;
       # Kill child
       kill( "TERM", $pid ) if $pid;
       undef $pid;
     }
   );

};

@@ system/logs.html.ep
<div class="page-header">
<h1>System Logs</h1>
</div>
<p>Times in GMT/UTC</p>
<div class="row-fluid">
<div class="span12">
<pre id="syslog">
     %== $self->txt_to_html( Mojo::Asset::File->new( path =>
'/var/log/messages' )->slurp );
</pre>

     % content_for javascript_footer => begin
<script>
       var events = new EventSource('<%= url_for '/system/log-es' %>');

       // Subscribe to "log" event
       events.addEventListener('log', function(event) {
         $("#syslog").append(event.data);
       }, false);
</script>
     %end
</div>
</div>


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »