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