Commit | Line | Data |
36cf3bcb |
1 | package Tak::JSONChannel; |
2 | |
3 | use JSON::PP qw(encode_json decode_json); |
4 | use IO::Handle; |
5 | use Scalar::Util qw(weaken); |
6 | use Moo; |
7 | |
8 | has read_fh => (is => 'ro', required => 1); |
9 | has write_fh => (is => 'ro', required => 1); |
10 | |
11 | sub BUILD { shift->write_fh->autoflush(1); } |
12 | |
77bf1d9b |
13 | sub read_message { |
36cf3bcb |
14 | my ($self) = @_; |
77bf1d9b |
15 | if (defined(my $line = readline($self->read_fh))) { |
36cf3bcb |
16 | if (my $unpacked = $self->_unpack_line($line)) { |
17 | return $unpacked; |
18 | } |
986f5290 |
19 | } else { |
20 | return [ 'close', 'channel' ]; |
36cf3bcb |
21 | } |
22 | } |
23 | |
24 | sub _unpack_line { |
25 | my ($self, $line) = @_; |
26 | my $data = eval { decode_json($line) }; |
27 | unless ($data) { |
77bf1d9b |
28 | $self->write_message(mistake => invalid_json => $@||'No data and no exception'); |
36cf3bcb |
29 | return; |
30 | } |
31 | unless (ref($data) eq 'ARRAY') { |
77bf1d9b |
32 | $self->write_message(mistake => message_format => "Not an ARRAY"); |
36cf3bcb |
33 | return; |
34 | } |
35 | unless (@$data > 0) { |
77bf1d9b |
36 | $self->write_message(mistake => message_format => "Empty request array"); |
36cf3bcb |
37 | return; |
38 | } |
39 | $data; |
40 | } |
41 | |
77bf1d9b |
42 | sub write_message { |
36cf3bcb |
43 | my ($self, @msg) = @_; |
44 | my $json = eval { encode_json(\@msg) }; |
45 | unless ($json) { |
77bf1d9b |
46 | $self->_raw_write_message( |
36cf3bcb |
47 | encode_json( |
77bf1d9b |
48 | [ failure => invalid_message => $@||'No data and no exception' ] |
36cf3bcb |
49 | ) |
50 | ); |
857f4834 |
51 | return; |
36cf3bcb |
52 | } |
77bf1d9b |
53 | $self->_raw_write_message($json); |
36cf3bcb |
54 | } |
55 | |
77bf1d9b |
56 | sub _raw_write_message { |
36cf3bcb |
57 | my ($self, $raw) = @_; |
31a246e4 |
58 | #warn "Sending: ${raw}\n"; |
36cf3bcb |
59 | print { $self->write_fh } $raw."\n"; |
60 | } |
61 | |
62 | 1; |