Files
scripts/rediscaht.pl
2025-06-03 23:03:08 +02:00

137 lines
3.0 KiB
Perl

#!/usr/bin/env perl
use Mojolicious::Lite;
use Mojo::Redis;
use Mojo::JSON 'j';
sub handler {
my $tag = shift;
return sub {
my $message = $_[1] || "Closed";
app->log->debug( "$tag: $message" )
};
}
app->attr( _redis => sub {
my $redis = Mojo::Redis->new;
$redis->on( error => handler("Pub Error") );
$redis->on( close => handler("Pub") );
return $redis;
});
helper redis => sub { shift->app->_redis };
app->attr( _chat => sub {
my $redis = shift->redis;
my $chat = $redis->new($redis); #clone
$chat->subscribe('chat');
$chat->on( error => handler("Sub Error") );
$chat->on( close => handler("Sub") );
return $chat;
});
helper chat => sub {
my ($self, $cb) = @_;
my $chat = $self->app->_chat;
$chat->on( message => $cb );
};
any '/' => sub {
my $c = shift;
my $name = $c->session('name');
if ( my $new_name = $c->param('name') ) {
$c->session( name => $new_name );
$name = $new_name;
} elsif ( ! defined $name ) {
return $c->redirect_to('login');
}
$c->render('chat');
};
any '/login';
any '/logout' => sub {
my $c = shift;
$c->session( expires => 1 );
$c->redirect_to('/');
};
websocket '/ws/chat' => sub {
my $c = shift;
my $name = $c->session('name');
Mojo::IOLoop->stream($c->tx->connection)->timeout(60*60);
$c->chat( sub {
my ($s, $chan, $message) = @_;
$c->app->log->debug( "Got: $message" );
$c->send({ text => $message });
} );
$c->on( json => sub {
my ($ws, $data) = @_;
$data->{name} = $name;
my $json = j($data);
$ws->app->log->debug( "Publishing: $json" );
$c->redis->publish( chat => $json );
});
#my $r = Mojo::IOLoop->recurring( 1 => sub {
# state $i = 1;
# $c->send({ json => { name => 'Joel', message => $i++ }});
#});
#$c->on( finish => sub { Mojo::IOLoop->remove($r) } );
};
app->start;
__DATA__
@@ layouts/basic.html.ep
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</head>
<body>
%= content
</body>
</html>
@@ login.html.ep
% layout 'basic';
% title 'Login';
%= form_for '/' => method => POST => begin
%= text_field 'name'
%= submit_button 'Login'
% end
@@ chat.html.ep
% layout 'basic';
% title 'Mojo+Redis Chat';
<input type="text" id="text"><button onclick="send()">Send</button><button onclick="disconnect()">Disconnect</button>
<div id="log"></div>
%= javascript begin
var ws;
var nows = 0;
function connect () {
if (!("WebSocket" in window)) {
nows = 1;
alert('Your browser does not support WebSockets!');
return;
}
ws = new WebSocket('<%= url_for('wschat')->to_abs %>');
ws.onmessage = function (e) {
console.log(e);
var data = JSON.parse(e.data);
$('#log').prepend('<p>' + data.name + ': ' + data.message + '</p>');
};
}
function send () {
var text = $('#text');
ws.send(JSON.stringify({ message: text.val() }));
text.val('');
}
function disconnect () { ws.close() }
$(function(){connect()});
% end