The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Hessian::Tiny::Client - Hessian RPC Client implementation in pure Perl

VERSION

Version 0.08

SYNOPSIS

use Hessian::Tiny::Client;

my $foo = Hessian::Tiny::Client->new(
    url => 'http://hessian.service.com/serviceName',
    version => 2, # hessian protocol version
);
my($stat,$res) = $foo->call('add',2,4);
if($stat == 0){ # success
    print "2 + 4 = $res";
}else{
    print "error: $Hessian::Tiny::Client::ErrStr";
}
...

DESCRIPTION

Hessian is a compact binary protocol for web communication in form of client/server RPC.

This module allows you to write Hessian clients in Perl. This module supports Hessian Protocol 1.0 and 2.0

SUBROUTINES/METHODS

new

my $foo = Hessian::Tiny::Client->new(
    url => 'http://hessian.service.com/serviceName', # mandatory
    version => 2, # default is 1
    debug => 1,   # add some debugging output (to STDERR)
    auth => [$http_user,$http_pass], # http basic auth, if needed
    hessian_flag => 1, # if you need strong typing in return value
);

'url' need to be a valid url, otherwise the constructor will return undef. 'version', hessian version either 1 or 2. 'debug', you probably don't need to set this flag. 'auth', if server requires this authentication. 'hessian_flag', default off, that means return value are automatically converted into native perl data; if set to true, you will get Hessian::Type::* object as return.

call

# for convinience, simple types can be passed directly
($stat,$res) = $foo->call('addInt',1,2);

# or use Hessian::Type::* for precise typing
($stat,$res) = $foo->call('method1',
    Hessian::Type::Date( Math::BigInt->new( $milli_sec ) ),
    Hessian::Type::Double( 3.14 ),
    Hessian::Type::List( length=>2,
                         data=>[
                                Hessian::Type::String->new('unicode_stream'),
                                Hessian::Type::Binary->new('bytes')
                         ] );
    Hessian::Type::Map( type=>'Car',
                        data=>{
                               'Make' => 'Toto',
                               'Modle' => 'XYZ'
                        } );
                                            
); # end call

if($stat == 0){
    # success

}elsif($stat == 1){
    # Hessian Fault
    print "Exception: $res->{code}, $res->{message}";
}else{
    # communication failure
    print "error: $res";
}

return value, $stat: 0 for success, 1 for Fault, 2 for communication errors; $res will hold error (Hessian::Fault or string) in case of unsuccessful call; $res will hold return value in case of successful call; normally Hessian types are converted to perl data directly, if you want strong typing in return value, you can set (hessian_flag => 1) in the constructor call new().

HESSIAN DATA TYPES

Null

$foo->call('argNull', Hessian::Type::Null->new() );

As return value, by default, you will get undef; when 'hessian_flag' is set to true, you will get Hessian::Type::Null.

True/False

$foo->call('argTrue',  Hessian::Type::True->new() );
$foo->call('argFalse', Hessian::Type::False->new() );

As return value, by default, you will get 1 (true) or undef (false); when 'hessian_flag' is set to true, you will get Hessian::Type::True or Hessian::Type::False as return value.

Integer

$foo->call('argInt', 250 );

No extra typing for Integer type. Note, if the number passed in falls outside the range of signed 32-bit integer, it will be passed as a Long type parameter (64-bit) instead.

Long

$foo->call('argLong', Math::BigInt->new(100000) ); # core module
$foo->call('argLong', Hessian::Type::Long->new('100000') ); # same as above

As return value, by default, you will get string representation of the number; when 'hessian_flag' is set to true, you will get Math::BigInt.

Double

$foo->call('argDouble', -2.50 ); # pass directly, if looks like floating point number
$foo->call('argDouble', Hessian::Type::Double(-2.50) ); # equivalent

As return value, by default, you will get the number directly; when 'hessian_flag' is set to true, you will get Hessian::Type::Double. Note, floating point numbers may appear slightly inaccurate, due to the binary nature of machines (not the protocol itself).

Date

$foo->call('argDate', Hessian::Type::Date->new($milli_sec) );
$foo->call('argDate', DateTime->now() ); # if you have this module installed

As return value, by default, you will get epoch seconds; when 'hessian_flag' is set to true, you will get Hessian::Type::Date (milli sec inside).

Binary/String

$foo->call('argBinary', Hessian::Type::Binary->new("hello world\n") );
$foo->call('argString', Hessian::Type::String->new("hello world\n") );
$foo->call('argString', Unicode::String->new("hello world\n") );

As return value, by default, you will get the perl string; when 'hessian_flag' is set to true, you will get Hessian::Type::Binary or Hessian::Type::String object.

XML

$foo->call('argXML', Hessian::Type::XML->new( $xml_string ) );

As return value, by default, you will get xml string; when 'hessian_flag' is set to true, you will get Hessian::Type::XML. Note, XML type is removed from Hessian 2.0 spec.

List

$foo->call('argList', [1,2,3] ); # untyped fixed length list
$foo->call('argList', Hessian::Type::List->new([1,2,3]); # same as above
$foo->call('argList', Hessian::Type::List->new(length=>3,data=>[1,2,3],type=>'Triplet');

As return value, by default, you will get array ref; when 'hessian_flag' is set to true, you will get Hessian::Type::List.

Map

$foo->call('argMap', {a=>1,b=>2,c=>3} ); # untyped map
$foo->call('argMap', Hessian::Type::Map->new({a=>1,b=>2,c=>3} ); # same as above
$foo->call('argMap', Hessian::Type::Map->new(type=>'HashTable',data=>{a=>1,b=>2,c=>3} ); # typed

As return value, by default, you will get hash ref (Tie::RefHash is used to allow non-string keys); when 'hessian_flag' is set to true, you will get Hessian::Type::Map.

Object

my $x = Hessian::Type::Object->new(
            type => 'my.package.LinkedList',
            data => {_value => 1, _rest => undef}
        );
my $y = Hessian::Type::Object->new(
            type => 'my.package.LinkedList',
            data => {_value => 2, _rest => $x}
        );
$foo->call('argObject',$y);

As return value, by default, you will get hash_ref (Tie::RefHash is used to allow non-string keys); when 'hessian_flag' is set to true, you will get Hessian::Type::Object. Note, Object is essentially a typed Map.

AUTHOR

Ling Du, <ling.du at gmail.com>

BUGS

Please report any bugs or feature requests to bug-hessian-tiny-client at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Hessian-Tiny-Client. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

TODO

Hessian::Tiny::Server, not sure if anyone will need to use the server part, except for testing maybe.

SUPPORT

You can find documentation for this module with the perldoc command.

perldoc Hessian::Tiny::Client

For information on the protocol itself, take a look at: http://hessian.caucho.com/

ACKNOWLEDGEMENTS

Algo LLC.

LICENSE AND COPYRIGHT

Copyright 2010 Ling Du.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.