.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "RPC::PlClient 3"
.TH RPC::PlClient 3 "2007-06-17" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
RPC::PlClient \- Perl extension for writing PlRPC clients
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& require RPC::PlClient;
\&
\& # Create a client object and connect it to the server
\& my $client = RPC::PlClient\->new(\*(Aqpeeraddr\*(Aq => \*(Aqjoes.host.de\*(Aq,
\& \*(Aqpeerport\*(Aq => 2570,
\& \*(Aqapplication\*(Aq => \*(AqMy App\*(Aq,
\& \*(Aqversion\*(Aq => \*(Aq1.0\*(Aq,
\& \*(Aquser\*(Aq => \*(Aqjoe\*(Aq,
\& \*(Aqpassword\*(Aq => \*(Aqhello!\*(Aq);
\&
\& # Create an instance of $class on the server by calling $class\->new()
\& # and an associated instance on the client.
\& my $object = $client\->Call(\*(AqNewHandle\*(Aq, $class, \*(Aqnew\*(Aq, @args);
\&
\&
\& # Call a method on $object, effectively calling the same method
\& # on the associated server instance.
\& my $result = $object\->do_method(@args);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
PlRPC (Perl \s-1RPC\s0) is a package that simplifies the writing of
Perl based client/server applications. RPC::PlServer is the
package used on the server side, and you guess what RPC::PlClient
is for. See \fBRPC::PlServer\fR\|(3) for this part.
.PP
PlRPC works by defining a set of methods that may be executed by the client.
For example, the server might offer a method \*(L"multiply\*(R" to the client. Now
a function call
.PP
.Vb 1
\& @result = $client\->Call(\*(Aqmultiply\*(Aq, $a, $b);
.Ve
.PP
on the client will be mapped to a corresponding call
.PP
.Vb 1
\& $server\->multiply($a, $b);
.Ve
.PP
on the server. The function calls result will be transferred to the
client and returned as result of the clients method. Simple, eh? :\-)
.SS "Client methods"
.IX Subsection "Client methods"
.ie n .IP "$client = new(%attr);" 4
.el .IP "\f(CW$client\fR = new(%attr);" 4
.IX Item "$client = new(%attr);"
(Class method) The client constructor. Returns a client object, connected
to the server. A Perl exception is thrown in case of errors, thus you
typically use it like this:
.Sp
.Vb 5
\& $client = eval { RPC::PlClient\->new ( ... ) };
\& if ($@) {
\& print STDERR "Cannot create client object: $@\en";
\& exit 0;
\& }
.Ve
.Sp
The method accepts a list of key/value pairs as arguments. Known arguments
are:
.RS 4
.IP "peeraddr" 8
.IX Item "peeraddr"
.PD 0
.IP "peerport" 8
.IX Item "peerport"
.IP "socket_proto" 8
.IX Item "socket_proto"
.IP "socket_type" 8
.IX Item "socket_type"
.IP "timeout" 8
.IX Item "timeout"
.PD
These correspond to the attributes \fIPeerAddr\fR, \fIPeerPort\fR, \fIProto\fR,
\&\fIType\fR and \fITimeout\fR of IO::Socket::INET. The server connection will be
established by passing them to IO::Socket::INET\->\fBnew()\fR.
.IP "socket" 8
.IX Item "socket"
After a connection was established, the IO::Socket instance will be stored
in this attribute. If you prefer establishing the connection on your own,
you may as well create an own instance of IO::Socket and pass it as attribute
\&\fIsocket\fR to the new method. The above attributes will be ignored in that
case.
.IP "application" 8
.IX Item "application"
.PD 0
.IP "version" 8
.IX Item "version"
.IP "user" 8
.IX Item "user"
.IP "password" 8
.IX Item "password"
.PD
it is part of the PlRPC authorization process, that the client
must obeye a login procedure where he will pass an application
name, a protocol version and optionally a user name and password.
These arguments are handled by the servers \fIApplication\fR, \fIVersion\fR
and \fIUser\fR methods.
.IP "compression" 8
.IX Item "compression"
Set this to off (default, no compression) or gzip (requires the
Compress::Zlib module).
.IP "cipher" 8
.IX Item "cipher"
This attribute can be used to add encryption quite easily. PlRPC is not
bound to a certain encryption method, but to a block encryption \s-1API.\s0 The
attribute is an object supporting the methods \fIblocksize\fR, \fIencrypt\fR
and \fIdecrypt\fR. For example, the modules Crypt::DES and Crypt::IDEA
support such an interface.
.Sp
Note that you can set or remove encryption on the fly (putting \f(CW\*(C`undef\*(C'\fR
as attribute value will stop encryption), but you have to be sure,
that both sides change the encryption mode.
.Sp
Example:
.Sp
.Vb 4
\& use Crypt::DES;
\& $cipher = Crypt::DES\->new(pack("H*", "0123456789abcdef"));
\& $client = RPC::PlClient\->new(\*(Aqcipher\*(Aq => $cipher,
\& ...);
.Ve
.IP "maxmessage" 8
.IX Item "maxmessage"
The size of messages exchanged between client and server is restricted,
in order to omit denial of service attacks. By default the limit is
65536 bytes.
.IP "debug" 8
.IX Item "debug"
Enhances logging level by emitting debugging messages.
.IP "logfile" 8
.IX Item "logfile"
By default the client is logging to syslog (Unix) or the event log (Windows).
If neither is available or you pass a \s-1TRUE\s0 value as \fIlogfile\fR, then logging
will happen to the given file handle, an instance of IO::Handle. If the
value is scalar, then logging will occur to stderr.
.Sp
Examples:
.Sp
.Vb 2
\& # Logging to stderr:
\& my $client = RPC::PlClient\->new(\*(Aqlogfile\*(Aq => 1, ...);
\&
\& # Logging to \*(Aqmy.log\*(Aq:
\& my $file = IO::File\->new(\*(Aqmy.log\*(Aq, \*(Aqa\*(Aq)
\& || die "Cannot create log file \*(Aqmy.log\*(Aq: $!";
\& my $client = RPC::PlClient\->new(\*(Aqlogfile\*(Aq => $file, ...);
.Ve
.RE
.RS 4
.RE
.ie n .IP "@result = $client\->Call($method, @args);" 4
.el .IP "\f(CW@result\fR = \f(CW$client\fR\->Call($method, \f(CW@args\fR);" 4
.IX Item "@result = $client->Call($method, @args);"
(Instance method) Calls a method on the server; the arguments are a method
name of the server class and the method call arguments. It returns the
method results, if successfull, otherwise a Perl exception is thrown.
.Sp
Example:
.Sp
.Vb 5
\& @results = eval { $client\->Call($method, @args };
\& if ($@) {
\& print STDERR "An error occurred while executing $method: $@\en";
\& exit 0;
\& }
.Ve
.ie n .IP "$cobj = $client\->ClientObject($class, $method, @args)" 4
.el .IP "\f(CW$cobj\fR = \f(CW$client\fR\->ClientObject($class, \f(CW$method\fR, \f(CW@args\fR)" 4
.IX Item "$cobj = $client->ClientObject($class, $method, @args)"
(Instance method) A set of predefined methods is available that make
dealing with client side objects incredibly easy: In short the client
creates a representation of the server object for you. Say we have an
object \f(CW$sobj\fR on the server and an associated object \f(CW$cobj\fR on the client:
Then a call
.Sp
.Vb 1
\& @results = $cobj\->my_method(@args);
.Ve
.Sp
will be immediately mapped to a call
.Sp
.Vb 1
\& @results = $sobj\->my_method(@args);
.Ve
.Sp
on the server and the results returned to you without any additional
programming. Here's how you create \f(CW$cobj\fR, an instance of
\&\fIRPC::PlClient::Object\fR:
.Sp
.Vb 1
\& my $cobj = $client\->ClientObject($class, \*(Aqnew\*(Aq, @args);
.Ve
.Sp
This will trigger a call
.Sp
.Vb 1
\& my $sobj = $class\->new(@args);
.Ve
.Sp
on the server for you. Note that the server has the ability to restrict
access to both certain classes and methods by setting \f(CW$server\fR\->{'methods'}
appropriately.
.SH "EXAMPLE"
.IX Header "EXAMPLE"
We'll create a simple example application, an \s-1MD5\s0 client. The server
will have installed the \s-1MD5\s0 module and create digests for us. We
present the client part only, the server example is part of the
RPC::PlServer man page. See \fBRPC::PlServer\fR\|(3).
.PP
.Vb 1
\& #!/usr/local/bin/perl
\&
\& use strict; # Always a good choice.
\&
\& require RPC::PlClient;
\&
\& # Constants
\& my $MY_APPLICATION = "MD5_Server";
\& my $MY_VERSION = 1.0;
\& my $MY_USER = ""; # The server doesn\*(Aqt require user
\& my $MY_PASSWORD = ""; # authentication.
\&
\& my $hexdigest = eval {
\& my $client = RPC::PlClient\->new
\& (\*(Aqpeeraddr\*(Aq => \*(Aq127.0.0.1\*(Aq,
\& \*(Aqpeerport\*(Aq => 2000,
\& \*(Aqapplication\*(Aq => $MY_APPLICATION,
\& \*(Aqversion\*(Aq => $MY_VERSION,
\& \*(Aquser\*(Aq => $MY_USER,
\& \*(Aqpassword\*(Aq => $MY_PASSWORD);
\&
\& # Create an MD5 object on the server and an associated
\& # client object. Executes a
\& # $context = MD5\->new()
\& # on the server.
\& my $context = $client\->ClientObject(\*(AqMD5\*(Aq, \*(Aqnew\*(Aq);
\&
\& # Let the server calculate a digest for us. Executes a
\& # $context\->add("This is a silly string!");
\& # $context\->hexdigest();
\& # on the server.
\& $context\->add("This is a silly string!");
\& $context\->hexdigest();
\& };
\& if ($@) {
\& die "An error occurred: $@";
\& }
\&
\& print "Got digest $hexdigest\en";
.Ve
.SH "AUTHOR AND COPYRIGHT"
.IX Header "AUTHOR AND COPYRIGHT"
The PlRPC-modules are
.PP
.Vb 2
\& Copyright (C) 1998, Jochen Wiedmann
\& Email: jochen.wiedmann at freenet.de
\&
\& All rights reserved.
.Ve
.PP
You may distribute this package under the terms of either the \s-1GNU\s0
General Public License or the Artistic License, as specified in the
Perl \s-1README\s0 file.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBPlRPC::Server\fR\|(3), \fBNet::Daemon\fR\|(3), \fBStorable\fR\|(3), \fBSys::Syslog\fR\|(3),
Win32::EventLog
.PP
An example application is the \s-1DBI\s0 Proxy client:
.PP
\&\fBDBD::Proxy\fR\|(3).