File Coverage

blib/lib/Mojolicious/Plugin/PubSub/WebSocket.pm
Criterion Covered Total %
statement 47 51 92.1
branch 7 10 70.0
condition n/a
subroutine 8 8 100.0
pod 1 3 33.3
total 63 72 87.5


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::PubSub::WebSocket;
2             $Mojolicious::Plugin::PubSub::WebSocket::VERSION = '0.05';
3             # ABSTRACT: Plugin to implement PubSub protocol using websocket
4              
5 2     2   56893 use Mojo::Base 'Mojolicious::Plugin';
  2         8  
  2         13  
6 2     2   371 use Mojo::WebSocket::PubSub::Syntax;
  2         6  
  2         23  
7              
8             sub register {
9 2     2 1 89 my ( $s, $app, $conf ) = @_;
10 2         19 $app->log->debug( "Loading " . __PACKAGE__ );
11              
12              
13 2         164 my $r = $app->routes;
14              
15 2     53   29 $app->helper( psws_clients => sub { state $clients = {} } );
  53         965  
16 2     19   258 $app->helper( psws_channels => sub { state $channels = {} } );
  19         495  
17              
18             $r->websocket('/psws')->to(
19             cb => sub {
20 19     19   200110 my $c = shift;
21 19         191 my $syn = new Mojo::WebSocket::PubSub::Syntax;
22 19         271 $syn->on( 'all' => sub { $s->psws_reply( $c, @_ ) } );
  25         357  
23 19         290 $c->on( json => sub { $syn->parse( $_[1] ); } );
  25         95525  
24             $c->on(
25             finish => sub {
26 8         21462 my ( $c, $code, $reason ) = @_;
27 8         46 my $id = $c->tx->connection;
28 8 50       253 return unless $c->isa('psws_clients');
29 0         0 my $client = $c->psws_clients->{$id};
30             delete $c->psws_channels->{ $client->{channel} }->{$id}
31 0 0       0 if ( exists $client->{channel} );
32 0         0 delete $c->psws_clients->{$id};
33 0         0 $c->app->log->debug( "PSWS: WebSocket "
34             . $c->tx->connection
35             . " closed with status $code" );
36             },
37 19         4633 );
38              
39 19         1330 $s->connected($c);
40             }
41 2         188 );
42             }
43              
44             sub connected {
45 19     19 0 45 my $s = shift;
46 19         38 my $c = shift;
47 19         63 my $id = $c->tx->connection;
48 19         361 $c->app->log->debug("PSWS: New connection from $id");
49 19         319 $c->psws_clients->{$id} = { tx => $c->tx };
50             }
51              
52             sub psws_reply {
53 25     25 0 84 my ( $s, $c, $syn, $event, $req ) = @_;
54 25         157 my $id = $c->tx->connection;
55 25         608 $req->{id} = $id;
56              
57 25 100       94 if ( $event eq 'listen' ) {
58 16         52 my $ch = $req->{ch};
59 16         167 $c->psws_channels->{$ch}->{$id} = 1;
60 16         70 $c->psws_clients->{$id}->{channel} = $ch;
61             }
62 25 100       75 if ( my $res_f = $syn->lookup->{ $req->{t} }->{reply} ) {
63 20         178 my $res = $res_f->( $req, $id );
64 20 100       75 if ( $event eq 'notify' ) {
65 3         10 my $msg = $req->{msg};
66 3         14 my $ch = $c->psws_clients->{$id}->{channel};
67 3         9 foreach
68 3         14 my $client ( grep !/$id/, keys %{$c->psws_channels->{$ch}} )
69             {
70 15         3032 $c->psws_clients->{$client}->{tx}->send( { json => $res } );
71             }
72             # now reply to sender
73 3         646 $res = $syn->notified($req);
74             }
75 20         70 $c->tx->send( { json => $res } );
76             }
77             }
78              
79             1;
80              
81             __END__