File Coverage

blib/lib/SockJS/Connection.pm
Criterion Covered Total %
statement 102 102 100.0
branch 14 20 70.0
condition 20 31 64.5
subroutine 21 21 100.0
pod 0 16 0.0
total 157 190 82.6


line stmt bran cond sub pod time code
1             package SockJS::Connection;
2              
3 9     9   602113 use strict;
  9         93  
  9         254  
4 9     9   45 use warnings;
  9         17  
  9         9010  
5              
6             sub new {
7 39     39 0 19072 my $class = shift;
8 39         77 my (%params) = @_;
9              
10 39         69 my $self = {};
11 39         65 bless $self, $class;
12              
13 39   50     198 $self->{type} = $params{type} || '';
14 39   50 6   197 $self->{close_cb} = $params{close_cb} || sub { };
15 39   50 4   183 $self->{write_cb} = $params{write_cb} || sub { };
16              
17 39         83 $self->{messages} = [];
18              
19 39         109 return $self;
20             }
21              
22 7     7 0 24 sub type { $_[0]->{type} }
23              
24             sub write_cb {
25 16     16 0 61 my $self = shift;
26              
27 16 50       53 if (@_) {
28 16         54 $self->{write_cb} = $_[0];
29             }
30              
31 16         63 return $self->{write_cb};
32             }
33              
34             sub close_cb {
35 6     6 0 10 my $self = shift;
36              
37 6 50       16 if (@_) {
38 6         13 $self->{close_cb} = $_[0];
39             }
40              
41 6         13 return $self->{close_cb};
42             }
43              
44             sub is_connected {
45 115     115 0 251 my $self = shift;
46              
47 115         382 return $self->{is_connected};
48             }
49              
50             sub connected {
51 38     38 0 131 my $self = shift;
52              
53 38         64 $self->{is_connected} = 1;
54 38         70 $self->{is_reconnecting} = 0;
55 38         61 $self->{is_closed} = 0;
56              
57 38         110 $self->_send_staged_messages;
58              
59 38         113 $self->fire_event('connect');
60              
61 38         101 return $self;
62             }
63              
64             sub reconnecting {
65 6     6 0 23 my $self = shift;
66              
67 6         11 $self->{is_reconnecting} = 1;
68              
69 6         12 return $self;
70             }
71              
72             sub is_reconnecting {
73 67     67 0 90 my $self = shift;
74              
75 67         240 return $self->{is_reconnecting};
76             }
77              
78             sub reconnected {
79 1     1 0 8 my $self = shift;
80              
81 1         2 $self->{is_reconnecting} = 0;
82              
83 1         3 $self->_send_staged_messages;
84              
85 1         3 return $self;
86             }
87              
88             sub closed {
89 7     7 0 12 my $self = shift;
90              
91 7 50       14 return if $self->is_closed;
92              
93 7         24 $self->{is_connected} = 0;
94 7         22 $self->{is_closed} = 1;
95              
96 7         22 $self->fire_event('close');
97              
98 7         9 return $self;
99             }
100              
101             sub aborted {
102 2     2 0 16 my $self = shift;
103              
104 2 50       11 return if $self->is_closed;
105              
106 2         5 $self->{is_connected} = 0;
107 2         4 $self->{is_closed} = 1;
108              
109 2 100       6 if (exists $self->{on_abort}) {
110 1         5 $self->fire_event('abort');
111             }
112             else {
113 1         3 $self->fire_event('close');
114             }
115              
116 2         3 return $self;
117             }
118              
119             sub is_closed {
120 34     34 0 53 my $self = shift;
121              
122 34         118 return $self->{is_closed};
123             }
124              
125             sub on {
126 8     8 0 71 my $self = shift;
127 8         20 my ($event, $cb) = @_;
128              
129 8         14 push @{$self->{"on_$event"}}, $cb;
  8         32  
130              
131 8         21 return $self;
132             }
133              
134             sub write {
135 24     24 0 60 my $self = shift;
136 24         48 my ($message) = @_;
137              
138 24 50 33     131 return $self unless defined $message && $message ne '';
139              
140 24 100 66     51 if (($self->is_connected || $self->is_closed)
      100        
141             && !$self->is_reconnecting)
142             {
143 7         22 $self->{write_cb}->($self, $message);
144             }
145             else {
146 17         26 push @{$self->{messages}}, $message;
  17         52  
147             }
148              
149 24         50 return $self;
150             }
151              
152             sub close {
153 7     7 0 30 my $self = shift;
154 7         16 my ($code, $message) = @_;
155              
156 7 50       17 if ($self->type ne 'raw_websocket') {
157 7   66     51 $self->{close_message} ||= do {
158 4   50     24 $code ||= 3000;
159 4   50     20 $message ||= 'Get away!';
160              
161 4         14 [int $code, $message];
162             };
163              
164             $self->write('c['
165             . $self->{close_message}->[0] . ',"'
166 7         31 . $self->{close_message}->[1]
167             . '"]');
168             }
169              
170 7         26 $self->{close_cb}->($self);
171              
172 7         54 $self->closed;
173              
174 7         14 return $self;
175             }
176              
177             sub fire_event {
178 52     52 0 74 my $self = shift;
179 52         91 my $event = shift;
180              
181 52 100       169 if (exists $self->{"on_$event"}) {
182 7         12 foreach my $ev (@{$self->{"on_$event"}}) {
  7         22  
183 7         18 $ev->($self, @_);
184             }
185             }
186              
187 52         97 return $self;
188             }
189              
190             sub _send_staged_messages {
191 39     39   58 my $self = shift;
192              
193 39   66     99 while ($self->is_connected
      100        
194             && !$self->is_reconnecting
195 50         178 && @{$self->{messages}})
196             {
197 14         27 my $message = shift @{$self->{messages}};
  14         34  
198 14         44 my $type = substr($message, 0, 1);
199              
200 14 100       37 if ($type eq 'a') {
201 1   66     14 while ($self->{messages}->[0]
202             && substr($self->{messages}->[0], 0, 1) eq $type)
203             {
204 1         2 my $next_message = shift @{$self->{messages}};
  1         3  
205              
206 1         6 $next_message =~ s{^a\[}{};
207 1         10 $message =~ s{\]}{,$next_message};
208             }
209             }
210              
211 14         40 $self->{write_cb}->($self, $message);
212             }
213             }
214              
215             1;