NAME
RMI::Client - connection to an RMI::Server
VERSION
This document describes RMI::Client v0.10.
SYNOPSIS
# simple
$c = RMI::Client::ForkedPipes->new();
# typical
$c = RMI::Client::Tcp->new(host => 'server1', port => 1234);
# roll-your-own...
$c = RMI::Client->new(reader => $fh1, writer => $fh2); # generic
$c->call_use('IO::File');
$c->call_use('Sys::Hostname');
$remote_obj = $c->call_class_method('IO::File','new','/tmp/myfile');
print $remote_obj->getline;
print <$remote_obj>;
$host = $c->call_function('Sys::Hostname::hostname')
$host eq 'server1'; #!
$remote_hashref = $c->call_eval('$main::h = { k1 => 111, k2 => 222, k3 => 333}');
$remote_hashref->{k4} = 444;
print sort keys %$remote_hashref;
print $c->call_eval('sort keys %$main::h'); # includes changes!
$c->use_remote('Sys::Hostname'); # this whole package is on the other side
$host = Sys::Hostname::hostname(); # possibly not this hostname...
our $c;
BEGIN {
$c = RMI::Client::Tcp->new(port => 1234);
$c->use_lib_remote;
}
use Some::Class; # remote!
DESCRIPTION
This is the base class for a standard RMI connection to an RMI::Server.
In most cases, you will create a client of some subclass, typically RMI::Client::Tcp for a network socket, or RMI::Client::ForkedPipes for a private out-of-process object server.
METHODS
call_use_lib($path);
Calls "use lib '$path'" on the remote side.
$c->call_use_lib('/some/path/on/the/server');
call_use($class)
Uses the Perl package specified on the remote side, making it available for later calls to call_class_method() and call_function().
$c->call_use('Some::Package');
call_class_method($class, $method, @params)
Does $class->$method(@params) on the remote side.
Calling remote constructors is the primary way to make a remote object.
$remote_obj = $client->call_class_method('Some::Class','new',@params);
$possibly_another_remote_obj = $remote_obj->some_method(@p);
call_function($fname, @params)
A plain function call made by name to the remote side. The function name must be fully qualified.
$c->call_use('Sys::Hostname');
my $server_hostname = $c->call_function('Sys::Hostname::hostname');
call_sub($subname, @params)
An alias for call_function();
call_eval($src,@args)
Calls eval $src on the remote side.
Any additional arguments are set to @_ before eval on the remote side, after proxying.
my $a = $c->call_eval('@main::x = (11,22,33); return \@main::x;'); # pass an arrayref back
push @$a, 44, 55; # changed on the server
scalar(@$a) == $c->call_eval('scalar(@main::x)'); # ...true!
use_remote($class)
Creases the effect of "use $class", but all calls of any kind for that namespace are proxied through the client. This is the most transparent way to get remote objects, since you can just call normal constructors and class methods as though the module were local. It does means that ALL objects of the given class must come from through this client.
# NOTE: you probably shouldn't do this with IO::File unless you
# _really_ want all of its files to open on the server,
# while open() opens on the client...
$c->use_remote('IO::File'); # never touches IO/File.pm on the client
$fh = IO::File->new('myfile'); # actually a remote call
print <$fh>; # printing rows from a remote file
require IO::File; # does nothing, since we've already "used" IO::File
The @ISA array is also bound to the remote @ISA, but all other variables must be explicitly bound on the client to be accessible. This may be changed in a future release.
Exporting does work. To turn it off, use empty braces as you would empty parens.
$c->use_remote('Sys::Hostname',[]);
To get this effect (and prevent export of the hostame() function).
use Sys::Hostname ();
use_lib_remote($path)
Installs a special handler into the local @INC which causes it to check the remote side for a class. If available, it will do use_remote() on that class.
use A;
use B;
BEGIN { $c->use_remote_lib; }; # do everything remotely from now on if possible...
use C; #remote!
use D; #remote!
use E; #local, b/c not found on the remote side
bind($varname)
Create a local transparent proxy for a package variable on the remote side.
$c->bind('$Some::Package::somevar')
$Some::Package::somevar = 123; # changed remotely
$c->bind('@main::foo');
push @main::foo, 11, 22 33; #changed remotely
ADDITIONAL EXAMPLES
create and use a remote hashref
This makes a hashref on the server, and makes a proxy on the client:
my $remote_hashref = $c->call_eval('{}');
This seems to put a key in the hash, but actually sends a message to the server to modify the hash.
$remote_hashref->{key1} = 100;
Lookups also result in a request to the server:
print $remote_hashref->{key1};
When we do this, the hashref on the server is destroyed, as since the ref-count on both sides is now zero:
$remote_hashref = undef;
put remote objects from one server in a remote hash on another
$c1 = RMI::Client::Tcp->new(host => 'host1', port => 1234); $c2 = RMI::Client::Tcp->new(host => 'host2', port => 1234); $c3 = RMI::Client::Tcp->new(host => 'host3', port => 1234);
$o1 = $c1->call_class_method('IO::File','new','/etc/passwd'); $o2 = $c2->call_class_method('IO::File','new','/etc/passwd');
$h = $c3->call_eval('{ handle1 => $_[0] }', $o1);
$h->{handle2} = $o2;
making a remote CODE ref, and using it with local and remote objects
my $local_fh = IO::File->new('/etc/passwd');
my $remote_fh = $c->call_class_method('IO::File','new','/etc/passwd');
my $remote_coderef = $c->call_eval('
sub {
my $f1 = shift; my $f2 = shift;
my @lines = (<$f1>, <$f2>);
return scalar(@lines)
}
');
my $total_line_count = $remote_coderef->($local_fh, $remote_fh);
BUGS AND CAVEATS
See general bugs in RMI for general system limitations
SEE ALSO
RMI, RMI::Client::Tcp, RMI::Client::ForkedPipes, RMI::Server
IO::Socket, Tie::Handle, Tie::Array, Tie:Hash, Tie::Scalar
AUTHORS
Scott Smith <sakoht@cpan.org>
COPYRIGHT
Copyright (c) 2008 - 2009 Scott Smith <sakoht@cpan.org> All rights reserved.
LICENSE
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
The full text of the license can be found in the LICENSE file included with this module.