Net-Async-WebSocket-JSON/lib/Net/Async/WebSocket/JSON/Protocol.pm
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
# (C) Paul Evans, 2017 -- leonerd@leonerd.org.uk
package Net::Async::WebSocket::JSON::Protocol;
use strict;
use warnings;
use base qw( Net::Async::WebSocket::Protocol );
Net::Async::WebSocket::Protocol->VERSION( '0.11' ); # on_text_frame
our $VERSION = '0.01';
=head1 NAME
C<Net::Async::WebSocket::Protocol> - send and receive JSON-encoded data over WebSockets
=head1 DESCRIPTION
This subclass of L<Net::Async::WebSocket::Protocol> provides some conveniences
for sending and receiving JSON-encoded data over WebSockets. Principly, it
provides one new method, L<send_json>, for encoding Perl values into JSON and
sending them, and one new method, L<on_json>, for decoding received JSON
content into Perl values when received.
=cut
=head1 EVENTS
The following events are invoked, either using subclass methods or CODE
references in parameters:
=head2 on_json
$self->on_json( $data )
$on_json->( $self, $data )
Invoked when a text frame is received and has been decoded from JSON. It is
passed the Perl data structure resulting from the decode operation.
=cut
sub _init
{
my $self = shift;
my ( $params ) = @_;
$self->SUPER::_init( $params );
$params->{json} //= do {
require JSON::MaybeXS;
JSON::MaybeXS->new;
};
}
=head1 PARAMETERS
The following named parameters may be passed to C<new> or C<configure>:
=over 8
=item json => OBJECT
Optional. The JSON codec instance. This must support C<encode> and C<decode>
methods compatible with those provided by L<JSON>, L<JSON::XS> or similar.
$text = $json->encode( $data )
$data = $json->decode( $text )
Note in particular that the C<$text> strings are Unicode character strings,
not UTF-8 encoded byte strings, and therefore the C<utf8> option must be
disabled.
If not provided, the L<< JSON::MaybeXS->new >> constructor is used to find a
suitable implementation.
=item on_json => CODE
CODE reference for event handler.
=back
=cut
sub configure
{
my $self = shift;
my %params = @_;
foreach (qw( json on_json )) {
$self->{$_} = delete $params{$_} if exists $params{$_};
}
# TODO: forbid on_text_frame
$self->SUPER::configure( %params );
}
sub on_text_frame
{
my $self = shift;
my ( $text ) = @_;
# TODO: try/catch
my $data = $self->{json}->decode( $text );
$self->invoke_event( on_json => $data );
}
=head1 METHODS
The following methods documented with a trailing call to C<< ->get >> return
L<Future> instances.
=cut
=head2 send_json
$self->send_json( $data )->get
Sends a text frame containing a JSON encoding of the Perl data structure
provided.
=cut
sub send_json
{
my $self = shift;
my ( $data ) = @_;
$self->send_text_frame( $self->{json}->encode( $data ) );
}
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;