سؤال

I am trying to understand the concept of JSON RPC and it's Perl implementation. Though I can fin d a lot of examples for Python/Java, I find surprisingly little or no examples for it in Perl.

I am following this example but am not sure it is complete. The example I had in mind was to add 2 integers. Now I have a very basic HTML page set up, like so:

<html>
<body>
    <input type="text" name="num1"><br>
    <input type="text" name="num2"><br>
    <button>Add</button>
</body>
</html>

Next, based on the example above, I have 3 files:

test1.pl

# Daemon version
use JSON::RPC::Server::Daemon;

# see documentation at:
# https://metacpan.org/pod/distribution/JSON-RPC/lib/JSON/RPC/Legacy.pm

my $server = JSON::RPC::Server::Daemon->new(LocalPort => 8080);
$server -> dispatch({'/test' => 'myApp'});
$server -> handle();

test2.pl

#!/usr/bin/perl

use JSON::RPC::Client;

my $client = new JSON::RPC::Client;

my $uri = 'http://localhost:8080/test';
my $obj = {
method => 'sum', # or 'MyApp.sum'
params => [10, 20],
};

my $res = $client->call( $uri, $obj );

if($res){
if ($res->is_error) {
print "Error : ", $res->error_message;
} else {
print $res->result;
}
} else {
print $client->status_line;
}

myApp.pl

package myApp;

#optionally, you can also
use base qw(JSON::RPC::Procedure);  # for :Public and :Private attributes

sub sum : Public(a:num, b:num) {
my ($s, $obj) = @_;
return $obj->{a} + $obj->{b};
}

1;

While I understand what these files individually do, I am at a complete loss when it comes to combining them and making them work together.

My questions are as follows:

  • Does the button in the HTML page come inside a tag (like we would normally do in a CGI-based program)? If yes, what file does that call? If no, then how do I pass the values to be added?
  • What is the order of execution of the 3 Perl files? Which one calls which one? How is the flow of execution?
  • When I tried to run the perl files from the CLI, i.e using $./test2.pl, I got the following error: Error 301 Moved Permanently. What moved permanently? which file was it trying to access? I tried running the files from withing /var/www/html and /var/www/html/test.

Some help in understanding the nuances of this would really be appreciated. Thanks in advance

هل كانت مفيدة؟

المحلول

Does the button in the HTML page come inside a tag (like we would *normally do in a CGI-based program)? If yes, what file does that call?* If no, then how do I pass the values to be added?

HTML has nothing at all to do with JSON-RPC. While the RPC call is done via an HTTP POST request, if you're doing that from the browser, you'll need to use XMLHttpRequest (i.e: AJAX). Unlink an HTML form post the Content-encoding: header will need to be something specific to JSON-RPC (e.g: application/json or similar), and you'll need to encode your form data via JSON.stringify and correctly construct the JSON-RPC "envelope", including the id, jsonrpc, method and params properties.

Rather than doing this by hand you might use a purpose-build JSON-RPC JavaScript client like the jQuery-JSONRP plugin (there are many others) -- although the protocol is so simple that implementations usually are less than 20 lines of code.

From the jQuery-RPC documentation, you'd set up the connection like this:

$.jsonRPC.setup({
  endPoint: '/ENDPOINT-ROUTE-GOES-HERE'
});

and you'd call the server-side method like this:

$.jsonRPC.request('sum', {
  params: [YOURNUMBERINPUTELEMENT1.value, YOURNUMBERINPUT2.value],
  success: function(result) {
    /* Do something with the result here */
  },
  error: function(result) {
    /* Result is an RPC 2.0 compatible response object */
  }
});

What is the order of execution of the 3 Perl files? Which one calls *which one? How is the flow of execution?*

You'll likely only need test2.pl for testing. It's an example implementation of a JSON-RPC client. You likely want your client to run in your web-browser (as described above). The client JavaScript will make an HTTP POST request to wherever test1.pl is serving content. (e.g: http://localhost:8080).

Or, if you want to keep your code as HTML<-->CGI, then you'll need to make JSON-RPC client calls from within your Perl CGI server-side code (which seems silly if it's on the same machine).

When test1.pl calls dispatch, the MyApp module will be loaded. Then, when test1.pl calls handle, the sum function in the MyApp package will be called.

The JSON::RPC::Server module takes care of marshalling from JSON-RPC to perl datastructures and back again around the call to handle. die()ing in sum should result in a JSON-RPC exception being transmitted to the calling client, rather than death of the test1.pl script.

When I tried to run the perl files from the CLI, i.e using *$./test2.pl, I got the following error: Error 301 Moved Permanently.* What moved permanently? which file was it trying to access? I tried *running the files from withing /var/www/html and /var/www/html/test.*

This largely depends the configuration of your machine. There's nothing obvious (in your code) to suggest that a 301 Moved Permanently would be issued in response to a valid JSON-RPC request.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top