File Coverage

blib/lib/POE/Component/Client/Bayeux/Transport/LongPolling.pm
Criterion Covered Total %
statement 21 96 21.8
branch 0 24 0.0
condition 0 2 0.0
subroutine 7 15 46.6
pod 0 8 0.0
total 28 145 19.3


line stmt bran cond sub pod time code
1             package POE::Component::Client::Bayeux::Transport::LongPolling;
2              
3 3     3   3482 use strict;
  3         6  
  3         140  
4 3     3   18 use warnings;
  3         9  
  3         82  
5 3     3   27 use POE;
  3         8  
  3         20  
6 3     3   1063 use Data::Dumper;
  3         7  
  3         161  
7 3     3   21 use HTTP::Request;
  3         6  
  3         128  
8 3     3   1949 use POE::Component::Client::Bayeux::Utilities qw(decode_json_response);
  3         13  
  3         244  
9              
10 3     3   21 use base qw(POE::Component::Client::Bayeux::Transport);
  3         8  
  3         3800  
11              
12             sub extra_states {
13             # return an array of method names in this class that I want exposed
14 0     0 0   return ( qw( openTunnelWith tunnelResponse ) );
15             }
16              
17             sub check {
18 0     0 0   my ($kernel, $heap, $types, $version, $xdomain) = @_[KERNEL, HEAP, ARG0, ARG1, ARG2];
19             }
20              
21             sub tunnelInit {
22 0     0 0   my ($kernel, $heap) = @_[KERNEL, HEAP];
23              
24             # Allow parent class to do error checking
25             #$class->SUPER::tunnelInit(@_);
26              
27 0           my %connect = (
28             channel => '/meta/connect',
29             clientId => $heap->{parent_heap}{clientId},
30             connectionType => 'long-polling',
31             );
32              
33 0           $kernel->yield('openTunnelWith', \%connect);
34             }
35              
36             sub openTunnelWith {
37 0     0 0   my ($kernel, $heap, @messages) = @_[KERNEL, HEAP, ARG0 .. $#_];
38 0           my $pheap = $heap->{parent_heap};
39 0           $pheap->{_polling} = 1;
40              
41             # Ensure clientId is defined
42 0           foreach my $message (@messages) {
43 0           $message->{clientId} = $pheap->{clientId};
44             }
45              
46 0           $pheap->{client}->logger->debug(">>> LongPolling tunnel >>>\n".Dumper(\@messages));
47              
48             # Create an HTTP POST request, encoding the messages into JSON
49 0           my $request = HTTP::Request->new('POST', $pheap->{remote_url},
50             [ 'content-type', 'text/json' ],
51             $pheap->{json}->encode(\@messages),
52             );
53              
54             # Create a UUID so I can collect meta info about this request
55 0           my $uuid = $pheap->{uuid}->create_str();
56 0           $heap->{_tunnelsOpen}{$uuid} = { opened => time() };
57              
58             # Use parent user agent to make request
59 0           $kernel->post( $pheap->{ua}, 'request', 'tunnelResponse', $request, $uuid );
60              
61             # TODO: use $heap->{parent_heap}{advice}{timeout} as a timeout for this connect to reply
62             }
63              
64             sub tunnelResponse {
65 0     0 0   my ($kernel, $heap, $request_packet, $response_packet) = @_[KERNEL, HEAP, ARG0, ARG1];
66 0           my $pheap = $heap->{parent_heap};
67 0           $pheap->{_polling} = 0;
68              
69 0           my $request_object = $request_packet->[0];
70 0           my $request_tag = $request_packet->[1]; # from the 'request' post
71 0           my $response_object = $response_packet->[0];
72              
73 0           my $meta = delete $heap->{_tunnelsOpen}{$request_tag};
74              
75 0           my $json;
76 0           eval {
77 0           $json = decode_json_response($response_object);
78             };
79 0 0         if ($@) {
80             # Ignore errors if shutting down
81 0 0         return if $pheap->{_shutdown};
82 0           die $@;
83             }
84              
85 0           $pheap->{client}->logger->debug("<<< LongPolling tunnel <<<\n".Dumper($json));
86              
87 0           foreach my $message (@$json) {
88 0           $kernel->post( $heap->{parent}, 'deliver', $message );
89 0 0         if ($message->{channel} eq '/meta/connect') {
90 0   0       $pheap->{advice} = $message->{advice} || {};
91             }
92             }
93              
94 0           $kernel->yield('tunnelCollapse');
95             }
96              
97             sub tunnelCollapse {
98 0     0 0   my ($kernel, $heap) = @_[KERNEL, HEAP];
99 0           my $pheap = $heap->{parent_heap};
100              
101 0           my $reconnect;
102 0 0         if ($pheap->{advice}) {
103 0           $reconnect = $pheap->{advice}{reconnect};
104             }
105 0 0         if (delete $pheap->{_reconnect}) {
106 0           $reconnect = 'handshake';
107             }
108 0 0         if ($reconnect) {
109 0 0         if ($reconnect eq 'none') {
    0          
110 0           die "Server asked us not to reconnect";
111             }
112             elsif ($reconnect eq 'handshake') {
113 0           $pheap->{_initialized} = 0;
114 0           $pheap->{_connected} = 0;
115 0           $kernel->yield('_stop');
116 0           $kernel->post( $heap->{parent}, 'handshake' );
117 0           return;
118             }
119             }
120              
121 0 0         return if (! $pheap->{_initialized});
122 0 0         if (delete $pheap->{_disconnect}) {
123 0           $pheap->{_connected} = 0;
124 0           return;
125             }
126              
127 0 0         if ($pheap->{_polling}) {
128 0           $pheap->{client}->logger->debug("tunnelCollapse: Wait for polling to end");
129 0           return;
130             }
131              
132 0 0         if ($pheap->{_connected}) {
133 0           my %connect = (
134             channel => '/meta/connect',
135             clientId => $pheap->{clientId},
136             connectionType => 'long-polling',
137             );
138              
139 0           $kernel->yield('openTunnelWith', \%connect);
140             }
141             }
142              
143             sub sendMessages {
144 0     0 0   my ($kernel, $heap, $messages) = @_[KERNEL, HEAP, ARG0];
145 0           my $pheap = $heap->{parent_heap};
146              
147 0           foreach my $message (@$messages) {
148 0           $message->{clientId} = $pheap->{clientId};
149             }
150              
151 0           $pheap->{client}->logger->debug(">>> LongPolling >>>\n".Dumper($messages));
152              
153             # Create an HTTP POST request, encoding the messages into JSON
154 0           my $request = HTTP::Request->new('POST', $pheap->{remote_url},
155             [ 'content-type', 'text/json' ],
156             $pheap->{json}->encode($messages),
157             );
158              
159             # Use parent user agent to make request
160 0           $kernel->post( $pheap->{ua}, 'request', 'deliver', $request );
161             }
162              
163             sub deliver {
164 0     0 0   my ($kernel, $heap, $request_packet, $response_packet) = @_[KERNEL, HEAP, ARG0, ARG1];
165 0           my $pheap = $heap->{parent_heap};
166              
167 0           my $request_object = $request_packet->[0];
168 0           my $request_tag = $request_packet->[1]; # from the 'request' post
169 0           my $response_object = $response_packet->[0];
170              
171 0           my $json = decode_json_response($response_object);
172              
173 0           $pheap->{client}->logger->debug("<<< LongPolling <<<\n" . Dumper($json));
174              
175 0           foreach my $message (@$json) {
176 0           $kernel->post( $heap->{parent}, 'deliver', $message );
177             }
178             }
179              
180             1;