line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2017 -- leonerd@leonerd.org.uk |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Net::Async::WebSocket::JSON::Protocol; |
7
|
|
|
|
|
|
|
|
8
|
2
|
|
|
2
|
|
31510
|
use strict; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
46
|
|
9
|
2
|
|
|
2
|
|
8
|
use warnings; |
|
2
|
|
|
|
|
4
|
|
|
2
|
|
|
|
|
43
|
|
10
|
2
|
|
|
2
|
|
8
|
use base qw( Net::Async::WebSocket::Protocol ); |
|
2
|
|
|
|
|
15
|
|
|
2
|
|
|
|
|
617
|
|
11
|
|
|
|
|
|
|
Net::Async::WebSocket::Protocol->VERSION( '0.11' ); # on_text_frame |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our $VERSION = '0.01'; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 NAME |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
C - send and receive JSON-encoded data over WebSockets |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
This subclass of L provides some conveniences |
22
|
|
|
|
|
|
|
for sending and receiving JSON-encoded data over WebSockets. Principly, it |
23
|
|
|
|
|
|
|
provides one new method, L, for encoding Perl values into JSON and |
24
|
|
|
|
|
|
|
sending them, and one new method, L, for decoding received JSON |
25
|
|
|
|
|
|
|
content into Perl values when received. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=cut |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
=head1 EVENTS |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
The following events are invoked, either using subclass methods or CODE |
32
|
|
|
|
|
|
|
references in parameters: |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
=head2 on_json |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
$self->on_json( $data ) |
37
|
|
|
|
|
|
|
$on_json->( $self, $data ) |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
Invoked when a text frame is received and has been decoded from JSON. It is |
40
|
|
|
|
|
|
|
passed the Perl data structure resulting from the decode operation. |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=cut |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub _init |
45
|
|
|
|
|
|
|
{ |
46
|
2
|
|
|
2
|
|
8327
|
my $self = shift; |
47
|
2
|
|
|
|
|
5
|
my ( $params ) = @_; |
48
|
2
|
|
|
|
|
15
|
$self->SUPER::_init( $params ); |
49
|
|
|
|
|
|
|
|
50
|
2
|
|
33
|
|
|
141
|
$params->{json} //= do { |
51
|
2
|
|
|
|
|
11
|
require JSON::MaybeXS; |
52
|
2
|
|
|
|
|
12
|
JSON::MaybeXS->new; |
53
|
|
|
|
|
|
|
}; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head1 PARAMETERS |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
The following named parameters may be passed to C or C: |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
=over 8 |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
=item json => OBJECT |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
Optional. The JSON codec instance. This must support C and C |
65
|
|
|
|
|
|
|
methods compatible with those provided by L, L or similar. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
$text = $json->encode( $data ) |
68
|
|
|
|
|
|
|
$data = $json->decode( $text ) |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
Note in particular that the C<$text> strings are Unicode character strings, |
71
|
|
|
|
|
|
|
not UTF-8 encoded byte strings, and therefore the C option must be |
72
|
|
|
|
|
|
|
disabled. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
If not provided, the L<< JSON::MaybeXS->new >> constructor is used to find a |
75
|
|
|
|
|
|
|
suitable implementation. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=item on_json => CODE |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
CODE reference for event handler. |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=back |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub configure |
86
|
|
|
|
|
|
|
{ |
87
|
7
|
|
|
7
|
1
|
3395
|
my $self = shift; |
88
|
7
|
|
|
|
|
25
|
my %params = @_; |
89
|
|
|
|
|
|
|
|
90
|
7
|
|
|
|
|
35
|
foreach (qw( json on_json )) { |
91
|
14
|
100
|
|
|
|
38
|
$self->{$_} = delete $params{$_} if exists $params{$_}; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
# TODO: forbid on_text_frame |
95
|
|
|
|
|
|
|
|
96
|
7
|
|
|
|
|
36
|
$self->SUPER::configure( %params ); |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
sub on_text_frame |
100
|
|
|
|
|
|
|
{ |
101
|
2
|
|
|
2
|
1
|
9237
|
my $self = shift; |
102
|
2
|
|
|
|
|
7
|
my ( $text ) = @_; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
# TODO: try/catch |
105
|
2
|
|
|
|
|
13
|
my $data = $self->{json}->decode( $text ); |
106
|
2
|
|
|
|
|
8
|
$self->invoke_event( on_json => $data ); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
=head1 METHODS |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
The following methods documented with a trailing call to C<< ->get >> return |
112
|
|
|
|
|
|
|
L instances. |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=cut |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head2 send_json |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
$self->send_json( $data )->get |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
Sends a text frame containing a JSON encoding of the Perl data structure |
121
|
|
|
|
|
|
|
provided. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=cut |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub send_json |
126
|
|
|
|
|
|
|
{ |
127
|
2
|
|
|
2
|
1
|
1632
|
my $self = shift; |
128
|
2
|
|
|
|
|
6
|
my ( $data ) = @_; |
129
|
|
|
|
|
|
|
|
130
|
2
|
|
|
|
|
24
|
$self->send_text_frame( $self->{json}->encode( $data ) ); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head1 AUTHOR |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Paul Evans |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=cut |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
0x55AA; |