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.04';
3             # ABSTRACT: Plugin to implement PubSub protocol using websocket
4              
5 2     2   46793 use Mojo::Base 'Mojolicious::Plugin';
  2         5  
  2         12  
6 2     2   362 use Mojo::WebSocket::PubSub::Syntax;
  2         4  
  2         24  
7              
8             sub register {
9 2     2 1 81 my ( $s, $app, $conf ) = @_;
10 2         17 $app->log->debug( "Loading " . __PACKAGE__ );
11              
12              
13 2         136 my $r = $app->routes;
14              
15 2     53   39 $app->helper( psws_clients => sub { state $clients = {} } );
  53         731  
16 2     19   227 $app->helper( psws_channels => sub { state $channels = {} } );
  19         330  
17              
18             $r->websocket('/psws')->to(
19             cb => sub {
20 19     19   161999 my $c = shift;
21 19         173 my $syn = new Mojo::WebSocket::PubSub::Syntax;
22 19         268 $syn->on( 'all' => sub { $s->psws_reply( $c, @_ ) } );
  25         296  
23 19         251 $c->on( json => sub { $syn->parse( $_[1] ); } );
  25         69877  
24             $c->on(
25             finish => sub {
26 8         19400 my ( $c, $code, $reason ) = @_;
27 8         34 my $id = $c->tx->connection;
28 8 50       173 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         4198 );
38              
39 19         1084 $s->connected($c);
40             }
41 2         156 );
42             }
43              
44             sub connected {
45 19     19 0 49 my $s = shift;
46 19         36 my $c = shift;
47 19         93 my $id = $c->tx->connection;
48 19         329 $c->app->log->debug("PSWS: New connection from $id");
49 19         261 $c->psws_clients->{$id} = { tx => $c->tx };
50             }
51              
52             sub psws_reply {
53 25     25 0 71 my ( $s, $c, $syn, $event, $req ) = @_;
54 25         106 my $id = $c->tx->connection;
55 25         445 $req->{id} = $id;
56              
57 25 100       81 if ( $event eq 'listen' ) {
58 16         53 my $ch = $req->{ch};
59 16         88 $c->psws_channels->{$ch}->{$id} = 1;
60 16         56 $c->psws_clients->{$id}->{channel} = $ch;
61             }
62 25 100       69 if ( my $res_f = $syn->lookup->{ $req->{t} }->{reply} ) {
63 20         161 my $res = $res_f->( $req, $id );
64 20 100       79 if ( $event eq 'notify' ) {
65 3         8 my $msg = $req->{msg};
66 3         22 my $ch = $c->psws_clients->{$id}->{channel};
67 3         8 foreach
68 3         10 my $client ( grep !/$id/, keys %{$c->psws_channels->{$ch}} )
69             {
70 15         2264 $c->psws_clients->{$client}->{tx}->send( { json => $res } );
71             }
72             # now reply to sender
73 3         633 $res = $syn->notified($req);
74             }
75 20         62 $c->tx->send( { json => $res } );
76             }
77             }
78              
79             1;
80              
81             __END__