Recipe 18.11 Writing an XML-RPC Server
18.11.1 Problem
You want to write a server for an
XML-RPC web service.
18.11.2 Solution
Use the SOAP-Lite distribution from CPAN, which supports XML-RPC.
Your server can be either standalone:
use XMLRPC::Transport::HTTP;
$daemon = XMLRPC::Transport::HTTP::Daemon
->new(LocalPort => $PORT)
->dispatch_to('ClassName')
->handle( );
or a CGI script:
use XMLRPC::Transport::HTTP;
$daemon = XMLRPC::Transport::HTTP::CGI
->dispatch_to('ClassName')
->handle( );
In both cases, incoming methods will be invoked on the class named in
the dispatch_to method (it will be
required if it is not already loaded):
package ClassName;
sub handler {
my ($class, $arg_hash_ref) = @_;
# ...
}
18.11.3 Discussion
The
SOAP-Lite toolkit's modules take care of translating between Perl's
native data structures and the XML representation of those values.
However, it's up to you how the server decides which method to invoke
when a request arrives. This process of matching an XML-RPC request
to a Perl function is known as dispatching.
It looks strange to see all those chained method invocation in the
Solution. When used to set a value, XMLRPC::Lite methods return their
invocation, which lets you chain methods rather than repeat
$daemon over and over again:
$daemon = XMLRPC::Transport::HTTP::Daemon;
$daemon->new(LocalPort => $PORT);
$daemon->dispatch_to('ClassName');
$daemon->handle( );
The new constructor takes IO::Socket::INET's
constructor parameters as well, so you can say ReuseAddr
=> 1, for example.
When you give the dispatch_to method a class name
argument (as in the Solution), the XML-RPC server looks for methods
in that class. If the server in the Solution receives a request for
the ClassName.hasBeen method (XML-RPC methods are
typically in IntraCaps), it invokes the
ClassName->hasBeen method for a response.
Give dispatch_to a method name or list of method
names, optionally qualified with a package name. This tells Perl that
only those methods should be invoked. For example, the following code
ensures that only the hasBeen and
willBe methods from the main
package and the canDo method from the
MonkeySea class are valid:
$daemon->dispatch_to('hasBeen', 'willBe', 'MonkeySea::canDo')
Finally, give dispatch_to a pathname (optionally,
as with method names or class names), and XMLRPC::Lite will load
modules as needed from that directory at runtime:
$daemon->dispatch_to('/path/to/exposed/modules', 'MyClass::API');
This means "all modules in
/path/to/exposed/modules and MyClass::API can be
called through XML-RPC." MyClass::API might have been preloaded, or
it might be found in @INC. This specifically does
not mean "only dispatch to the MyClass::API in
/path/to/exposed/modules."
18.11.4 See Also
Recipe 18.12; Recipe 18.13
|