#!/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
' + data.name + ': ' + data.message + '
'); }; } function send () { var text = $('#text'); ws.send(JSON.stringify({ message: text.val() })); text.val(''); } function disconnect () { ws.close() } $(function(){connect()}); % end