File Coverage

blib/lib/WWW/Pusher/Client.pm
Criterion Covered Total %
statement 28 43 65.1
branch 1 8 12.5
condition 0 2 0.0
subroutine 10 13 76.9
pod 2 3 66.6
total 41 69 59.4


line stmt bran cond sub pod time code
1             package WWW::Pusher::Client;
2             # ABSTRACT: Laughably incomplete Perl client for Pusher WS API
3              
4 1     1   734851 use strict;
  1         3  
  1         44  
5 1     1   6 use warnings;
  1         2  
  1         30  
6 1     1   1020 use Moo;
  1         20334  
  1         7  
7 1     1   3167 use JSON;
  1         19467  
  1         6  
8 1     1   1273 use AnyEvent::WebSocket::Client;
  1         256285  
  1         48  
9 1     1   11 use Digest::SHA qw(hmac_sha256_hex);
  1         3  
  1         1008  
10              
11             has 'auth_key' => (
12             is => 'rw' ,
13             required => 1
14             );
15              
16             has 'secret' => (
17             is => 'rw',
18             required => 1
19             );
20              
21             has 'channel' => (
22             is => 'rw',
23             predicate => 'has_channel'
24             );
25              
26             has 'scheme' => (
27             is => 'rw',
28             default => 'ws'
29             );
30              
31             has 'port' => (
32             is => 'rw',
33             default => 80
34             );
35              
36             has 'client' => (
37             is => 'rw',
38             lazy => 1,
39             default => sub { shift->{client} // AnyEvent::WebSocket::Client->new }
40             );
41              
42             has 'ws_url' => (
43             is => 'ro',
44             lazy => 1,
45             builder => sub {
46 1     1   2236 my $self = shift;
47              
48 1         44 return $self->{scheme} . $self->{_pusher_base} . $self->{port}
49             . "/app/" . $self->{auth_key}
50             . "?protocol=" . $self->{_protocol}
51             . "&client=" . $self->{_client_name}
52             . "&version=" . $self->{_version}
53             }
54             );
55              
56             has 'ws_conn' => (
57             is => 'rw',
58             lazy => 1,
59             builder => sub {
60 1     1   512 my $self = shift;
61 1         14 return AnyEvent::WebSocket::Client->new->connect($self->ws_url)->recv;
62             }
63             );
64              
65             has '_pusher_base' => (
66             is => 'ro',
67             default => '://ws.pusherapp.com:'
68             );
69              
70             has '_protocol' => (
71             is => 'ro',
72             default => 7
73             );
74              
75             has '_client_name' => (
76             is => 'ro',
77             default => 'perl-pusher-client'
78             );
79              
80             has '_version' => (
81             is => 'ro',
82             default => '0.001'
83             );
84              
85             has '_socket_id' => (
86             is => 'rw',
87             );
88              
89              
90             sub BUILD {
91 1     1 0 4395 my $self = shift;
92              
93             $self->ws_conn->on(
94             next_message => sub {
95 0     0   0 my ($conn, $message) = @_;
96 0         0 my $body = from_json($message->decoded_body);
97              
98 0 0       0 if ($body->{event} eq 'pusher:connection_established') {
99 0         0 $self->_socket_id(from_json($body->{data})->{socket_id});
100              
101 0 0       0 $self->subscribe($self->channel) if $self->has_channel;
102             }
103             else {
104 0         0 die 'Connection error?' . $message->decoded_body;
105             }
106 1         8 });
107             }
108              
109              
110             sub subscribe {
111 0     0 1 0 my $self = shift;
112 0         0 my $data = {
113             channel => $self->channel
114             };
115 0 0       0 if ($self->channel =~ /^private\-/) {
116 0         0 $data->{auth} = $self->_socket_auth($self->channel);
117             }
118 0         0 $self->ws_conn->send(to_json({
119             event => 'pusher:subscribe',
120             data => $data
121             }));
122             }
123              
124             sub _socket_auth {
125 1     1   253745 my ($self, $channel) = @_;
126 1 50       8 die 'Missing socket_id, sorry...' unless $self->_socket_id;
127              
128             # see http://pusher.com/docs/auth_signatures for more information
129 1         5 my $plainSignature = $self->_socket_id . ':' . $channel;
130 1         38 return $self->auth_key . ':' . hmac_sha256_hex($plainSignature, $self->secret);
131             }
132              
133              
134             sub trigger {
135 0     0 1   my $self = shift;
136 0   0       my $event = shift // 'ws update';
137 0           my $message = shift;
138              
139 0           $self->ws_conn->send(to_json({
140             event => $event,
141             channel => $self->channel,
142             data => $message
143             }));
144             }
145              
146              
147             1;
148              
149             __END__