Snippets

Brian Medley Attempt at DBI trace in a websocket

Created by Brian Medley
use Mojolicious::Lite;
use DBI;
use PerlIO::via::DBLog;
use DBLog;
use DateTime;
    

use 5.20.0;
use experimental 'signatures';

helper db => sub {
    my $self = shift;
    
    return $self->{dbh} if $self->{dbh};
    
    my $dsn = "dbi:SQLite:dbname=joy";
    
    $self->stash("dblog") // $self->stash("dblog", DBLog->new($self->req_count));

    open(my $fh, '>:via(DBLog)', $self->stash("dblog")) or die;
    
    my $dbh = DBI->connect($dsn);
    
    $dbh->trace('SQL', $fh);
    
    $self->stash("fh", $fh);
    
    return $self->{dbh} = $dbh;
};

helper req_count => sub {
    state $count = 0;

    ++$count;
};

helper print_log => sub {
    my $self = shift;
    
    my $text = '';
    
    my $dblog = $self->stash("dblog");
    
    foreach my $log(@{$dblog->{queries}}) {
      $text = $text . "$log\n";
    }
    
    return $text;
};

get '/' => 'index';

my $clients = {};

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

    app->log->debug(sprintf 'Client connected: %s', $self->tx);

    my $id = sprintf "%s", $self->tx;
    $clients->{$id} = $self->tx;

    $self->on(message => sub {
        my ($self, $msg) = @_;

        my $dt = DateTime->now( time_zone => 'Asia/Tokyo');

        my $sth = $self->db->prepare("INSERT INTO test (name) VALUES (?)");
        $sth->execute($msg);

        if ("timings" eq $msg) {
            for (keys %$clients) {
                $clients->{$_}->send({json => {
                    hms  => $dt->hms,
                    text => $self->print_log,
                }});
            }

            return;
        }

        for (keys %$clients) {
            $clients->{$_}->send({json => {
                hms  => $dt->hms,
                text => $msg,
            }});
        }
    });

    $self->on(finish => sub {
        app->log->debug('Client disconnected');
        delete $clients->{$id};
    });
};

app->db->do("CREATE TABLE IF NOT EXISTS test (name VARCHAR NOT NULL, quantity INTEGER NOT NULL DEFAULT 0)");

app->start;

__DATA__
@@ index.html.ep
<html>
  <head>
    <title>WebSocket Client</title>
    <script
      type="text/javascript"
      src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
    ></script>
    <script type="text/javascript" src="ws.js"></script>
    <style type="text/css">
      textarea {
          width: 40em;
          height:10em;
      }
    </style>
  </head>
<body>

<h1>Mojolicious + WebSocket</h1>

<p><input type="text" id="msg" /></p>
<textarea id="log" readonly></textarea>

</body>
</html>

@@ ws.js
$(function () {
  $('#msg').focus();

  var log = function (text) {
    $('#log').val( $('#log').val() + text + "\n");
  };

  var ws = new WebSocket('ws://localhost:3000/echo');
  ws.onopen = function () {
    log('Connection opened');
  };

  ws.onmessage = function (msg) {
    var res = JSON.parse(msg.data);
    log('[' + res.hms + '] ' + res.text); 
  };

  $('#msg').keydown(function (e) {
    if (e.keyCode == 13 && $('#msg').val()) {
        ws.send($('#msg').val());
        $('#msg').val('');
    }
  });
});

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.