User Tools

Site Tools


Differences

This shows you the differences between two versions of the page.

Link to this comparison view

perl:json-rpc [2020-02-15 00:57] (current)
Line 1: Line 1:
 +=====Simple JSON RPC on Perl=====
 +
 +Now w/o error handling.
 +You can use any transport. In the example I use memory.
 +
 +
 +<code perl json-rpc.pl>​
 +#​!/​usr/​bin/​env perl
 +
 +# --- Dispatcher, Server side 
 +package aRPCD;
 +
 +use strict;
 +use warnings;
 +use Scalar::​Util qw(reftype);​
 +use Mojo::Util qw(dumper);
 +use Mojo::JSON qw(encode_json decode_json);​
 +
 +sub new {
 +    my $class = shift;
 +    my $self = {
 +         func => undef
 +    };
 +    bless $self, $class;
 +    return $self;
 +}
 +
 +sub add {
 +    my ($self, $key, $val) = @_;
 +    my %ret;
 +    $self->​{func}->​{$key} = $val;
 +    $self;
 +}
 +
 +sub call {
 +    my ($self, $name, @args) = @_;
 +    my $subr = $self->​{func}->​{$name};​
 +    return undef unless $subr;
 +    $subr->​(@args);​
 +}
 +
 +sub exist {
 +    my ($self, $name, @args) = @_;
 +    return undef unless $self->​{func}->​{$name};​
 +    1;
 +}
 +
 +sub error {
 +    my ($name, $id, $code, $message) = @_;
 +    $id ||= 1;
 +    $message ||= '​generic error';​
 +    my $body = {
 +        jsonrpc => "​2.0",​
 +        error => {
 +            code => $code,
 +            message => $message,
 +        },
 +        id => $id
 +    };
 +    encode_json($body);​
 +}
 +
 +sub result {
 +    my ($self, $id, $res) = @_;
 +    $id ||= 1;
 +    my $body = {
 +        jsonrpc => "​2.0",​
 +        result => $res,
 +        id => $id
 +    };
 +    encode_json($body);​
 +}
 +
 +sub jcall {
 +    my ($self, $str) = @_;
 +    my $jreq = decode_json($str);​
 +    my $method = $jreq->​{method};​
 +    my $params = $jreq->​{params};​
 +    my $id = $jreq->​{id};​
 +    my $res;
 +    unless (reftype $params) {
 +        $res = $self->​call($method,​ $params);
 +    } elsif (reftype $params eq '​ARRAY'​) {
 +        my @params = @{$params};
 +        $res =  $self->​call($method,​ @params);
 +    } elsif (reftype $params eq '​HASH'​) {
 +        my %params = %{$params};
 +        $res =  $self->​call($method,​ %params);
 +    }
 +    $self->​result($id,​ $res);
 +}
 +
 +1;
 +
 +# --- Serializator,​ Client side
 +package aRPCC;
 +
 +use strict;
 +use warnings;
 +use Scalar::​Util qw(reftype);​
 +use Mojo::Util qw(dumper);
 +use Mojo::JSON qw(encode_json decode_json);​
 +
 +sub new {
 +    my ($class, $url) = @_;
 +    my $self = {
 +         url => $url
 +    };
 +    bless $self, $class;
 +    return $self;
 +}
 +
 +sub json {
 +    my ($self, $name, $params) = @_;
 +    my $id = 1;
 +    my $body = {
 +        jsonrpc => "​2.0",​
 +        method => $name,
 +        params => $params,
 +        id => $id
 +    };
 +    encode_json($body);​
 +}
 +
 +1;
 +
 +use strict;
 +use warnings;
 +use Mojo::JSON qw(j decode_json encode_json);​
 +use Mojo::Util qw(dumper);
 +use Scalar::​Util qw(reftype);​
 +
 +sub plus {
 +    my (%args) = @_;
 +    my $n = $args{a} += $args{b};
 +    { a => 1, n => $n };
 +}
 +
 +sub plus2 {
 +    my ($a, $b) = @_;
 +    $b ||= 0;
 +    $a += $b;
 +}
 +
 +my $r = aRPCD->​new;​
 +$r->​add('​plus'​ => \&​plus);​
 +$r->​add('​plus2'​ => \&​plus2);​
 +
 +my $c = aRPCC->​new;​
 +
 +print $c->​json('​plus',​ { a => 12, b => 16 }), "​\n";​
 +print $c->​json('​plus',​ [[ 12, 16 ], "​a"​]),​ "​\n";​
 +print $c->​json('​plus',​ 12), "​\n";​
 +
 +my $j = $c->​json('​plus',​ { a => 12, b => 3 });
 +print $r->​jcall($j),​ "​\n";​
 +
 +my $j2 = $c->​json('​plus2',​ [12, 3]);
 +print $r->​jcall($j2),​ "​\n";​
 +
 +$j2 = $c->​json('​plus2',​ 12);
 +print $r->​jcall($j2),​ "​\n";​
 +</​code>​
 +
 +===Out===
 +
 +<​code>​
 +{"​id":​1,"​jsonrpc":"​2.0","​method":"​plus","​params":​{"​a":​12,"​b":​16}}
 +{"​id":​1,"​jsonrpc":"​2.0","​method":"​plus","​params":​[[12,​16],"​a"​]}
 +{"​id":​1,"​jsonrpc":"​2.0","​method":"​plus","​params":​12}
 +
 +{"​id":​1,"​jsonrpc":"​2.0","​result":​{"​a":​1,"​n":​15}}
 +{"​id":​1,"​jsonrpc":"​2.0","​result":​15}
 +{"​id":​1,"​jsonrpc":"​2.0","​result":​12}
 +</​code>​
 +
 +----
 +[<>]