Re: using the RPC::XML perl module, getting started

Ted Pedersen <[email protected]> Fri, 14 Jan 2011 11:02:59 -0600
Newsgroups gmane.text.xml.rpc.specification
Message-ID <[email protected]>
Greetings all,

I have the fortune telling server described in Programming Web Services with
Perl up and running on :

maraca.d.umn.edu:31135

I'll plan on keeping that there, in the event anyone would like to test
clients. If you do something clever please do tell. :)

Below is the server cod that is running, along with the fortune module
itself. Again, these are taken from the above mentioned book.

Enjoy,
Ted

-------------------------------------------------
server.pl----------------------------------------

#!/usr/bin/perl -w

# This is an example program from Programming Web Services with Perl,
# by Randy Ray and Pavel Kulchenko

use strict;
use warnings;

use XRFortune;
use RPC::XML::Server;

# The object created by the constructor will be used to
# chain on a set of calls to add_proc() (which means it
# isn't necessary to deal with the local routines being
# called as methods), and then drop directly into the
# server_loop() method.

RPC::XML::Server->new(port => 31135)
    # add_proc can take a pre-created RPC::XML::Procedure
    # object, or a hash reference.
    ->add_proc({ name => 'books',
                 signature => [ 'array',
                                'array string',
                                'array array' ],
                 code => \&XRFortune::books })
    # It gets called once for each routine being made
    # public by the server.
    ->add_proc({ name => 'fortune',
                 signature => [ 'array',
                                'array string',
                                'array array' ],
                 code => \&XRFortune::fortune })
    # There are other ways of specifying the server-side
    # procedures, but for an example of this size, this way
    # is just as efficient.
    ->add_proc({ name => 'weighted_fortune',
                 signature => [ 'array',
                                'array string',
                                'array array' ],
                 code => \&XRFortune::weighted_fortune })
    # This method will only return after a signal interrupts
    # it.
    ->server_loop;

exit;

-------------------------------------------------------------------------------------------------------

---------------------------------- XRFortune.pm
-----------------------------------------------

package XRFortune;

# This is an example program from Programming Web Services with Perl,
# by Randy Ray and Pavel Kulchenko

use 5.6.0;
use strict;
use vars qw($FORTUNE %BOOKS);
use subs qw(books fortune weighted_fortune);

BEGIN {
    # Locate the fortune program. Look in some standard
    # places, then loop over the user's PATH.
    for my $path (qw(/bin /usr/bin /usr/games),
                  split(':', $ENV{PATH})) {
        if (-e "$path/fortune" && -x _) {
            $FORTUNE = "$path/fortune";
            last;
        }
    }
    die "No 'fortune' command found!\n"
        unless $FORTUNE;

    # Calling fortune -f lists the books it knows, but the
    # output goes to STDERR for some reason.
    my @books = qx($FORTUNE -f 2>&1); shift(@books);
    chomp(@books);
    $BOOKS{(reverse split(/ /))[0]}++ for (@books);
}

1;

# If called with no arguments, returns the list of known
# books as a list reference. If one or more book names were
# passed, then take the list and return only the elements
# from it that are known books (pruning operation).
sub books {
    my $list = shift || '';

    my @prune = $list ? (ref $list ? @$list : ($list)) : ();
    my @books;

    if (@prune) {
        @books = sort grep($BOOKS{$_}, @prune);
    } else {
        @books = sort keys %BOOKS;
    }

    \@books;
}

# Get and return one fortune. With no arguments, just call
# the command. With one or more books, limit the selection
# of quotes to those books. When the fortune is extracted,
# take off the OS-dependent newlines and return the lines
# of text as a list reference.
sub fortune {
    my $book = shift || '';

    my @lines;
    my $exec = $FORTUNE;
    my @books = $book ? (ref $book ? @$book : ($book)) : ();
    if (@books) {
        my @bad;
        if (@bad = grep(! $BOOKS{$_}, @books)) {
            local $" = ', ';
            die "fortune: Unknown books (@bad)";
        } else {
            $exec .= " @books";
        }
    }

    chomp(@lines = `$exec`);
    \@lines;
}

# This also retrieves one fortune. However, the arguments
# here are more than just a list of books to restrict the
# search to. If a list reference is passed, use those books
# but weight them all equally in the search. If a hash
# reference is passed, its keys should be books and the
# corresponding values are the integer weights for each
# book. The weights must add up to 100.
sub weighted_fortune {
    my $weights = shift;

    die 'weighted_fortune: Must be called with array of ' .
        "books or struct of weights and books\n"
        unless ref $weights;

    my @lines;
    my $exec = $FORTUNE;
    if (ref($weights) eq 'ARRAY') {
        # Use our own books() call to ensure all the passed
        # books are valid
        $weights = books($weights);
        # The -e flag makes all books equal in weight
        $exec .= " -e @$weights";
    } else {
        # Trickier: must ensure that the weights add up to
        # 100%, even though pruning the list may mean that
        # one or more are dropped.
        my $total_weight;
        my $books = books([ keys %$weights ]);
        $total_weight += $weights->{$_} for (@$books);
        die 'weighted_fortune: Weights must add up to 100' .
            " (total is $total_weight)\n"
            unless ($total_weight == 100);
        $exec .= " $weights->{$_}% $_" for (@$books);
    }

    # As with fortune() above, drop the OS-dependent
    # newline characters and return a list reference.
    chomp(@lines = `$exec`);
    \@lines;
}

--------------------------------------------------------------------------------------------------

On Fri, Jan 14, 2011 at 3:24 AM, Gaetano Giunta <[email protected]>wrote:

>
>
> Bryan Henderson <[email protected] <bryanh%40giraffe-data.com>>
> wrote on 14/01/2011 00:06:
>
> >
> > >There is a second example in the book based on the OReilly Meerkat
> service,
> > >and that's a complete example with client and server, but as best I can
> tell
> > >this service is no longer available (so I can't run the examples).
> >
> > Yes, Meerkat died around 2006, I think.
> >
> > There also used to be servers and clients available to do full validation
> > of clients and servers respectively, on xmlrpc.com I believe. But I
> don't
> > know of any today.
> >
> > Can anyone suggest an XML-RPC server on the web that implements some
> > simple method so someone could use it to test a client?
> >
> http://phpxmlrpc.sourceforge.net/server.php
>
> bye
> Gaetano
>
> >
> >
> > I could put up a server dedicated to that purpose if there's nothing else
> > available.
> >
> > --
> > Bryan Henderson San Jose, California
> >
> >
>
> [Non-text portions of this message have been removed]
>
>  
>



-- 
Ted Pedersen
http://www.d.umn.edu/~tpederse


[Non-text portions of this message have been removed]



------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/xml-rpc/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/xml-rpc/join
    (Yahoo! ID required)

<*> To change settings via email:
    [email protected] 
    [email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/