AMF-Connection

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

Changes
examples/amfclient.pl
examples/get-brightcove-videos-metadata.pl
lib/AMF/Connection.pm
lib/AMF/Connection/InputStream.pm
lib/AMF/Connection/Message.pm
lib/AMF/Connection/MessageBody.pm
lib/AMF/Connection/MessageHeader.pm
lib/AMF/Connection/OutputStream.pm
Makefile.PL
MANIFEST			This list of files
README
t/00_load.t
TODO
META.yml                                 Module YAML meta-data (added by MakeMaker)
META.json                                Module JSON meta-data (added by MakeMaker)

examples/amfclient.pl  view on Meta::CPAN


my $params = [  "italy" ];
my ($response) = $client->call( $service.'.'.$method, $params );

my $json = JSON->new;
$json->ascii(1);
$json->utf8(1);
$json->pretty(1);
$json->allow_blessed(1);
$json->convert_blessed(1);
my $json_data = $json->encode( $response->getData );

if ( $response->is_success ) {
        print $json_data;
} else {
        die "Can not send remote request for $service.$method method with params on $endpoint using AMF".$client->getEncoding()." encoding:\n".$json_data."\n";
        };

examples/get-brightcove-videos-metadata.pl  view on Meta::CPAN

                                                     ];

my $response = $client->call( $service.'.'.$method, $params );

my $json = JSON->new;
$json->ascii(1);
$json->utf8(1);
$json->pretty(1);
$json->allow_blessed(1);
$json->convert_blessed(1);
my $json_data = $json->encode( $response->getData );

if ( $response->is_success ) {
	print $json_data;
} else {
	die "Can not send remote request for $service.$method method with params on $endpoint using AMF".$client->getEncoding()." encoding:\n".$json_data."\n";
	};

lib/AMF/Connection.pm  view on Meta::CPAN

        my $result_object = $response->getData();
	# ...
  } else {
        die "Can not send remote request for $service.$method method on $endpoint\n";
        };

  my @response = $client->callBatch ( { "operation" => $service.$method", "arguments" => \@params }, ... );

=head1 DESCRIPTION

I was looking for a simple Perl module to automate data extraction from an existing Flash+Flex/AMS application, and I could not find a decent client implementation. So, this module was born based on available online documentation.

This module has been inspired to SabreAMF PHP implementation of AMF client libraries.

AMF::Connection is meant to provide a simple AMF library to write client applications for invocation of remote services as used by most flex/AIR RIAs. 

The module includes basic support for synchronous HTTP/S based RPC request-response access, where the client sends a request to the server to be processed and the server returns a response to the client containing the processing outcome. Data is sent...

AMF0 and AMF3 support is provided using the Storable::AMF module. While HTTP/S requestes to the AMF endpoint are carried out using the LWP::UserAgent module. The requests are sent using the HTTP POST method as AMF0 encoded data by default. AMF3 encod...

If encoding is set to AMF3 the Flex Messaging framework is used on returned responses content (I.e. objects casted to "flex.messaging.messages.AcknowledgeMessage" and "flex.messaging.messages.ErrorMessage" are returned).

Simple batch requests and responses is provided also.

See the sample usage synopsis above to start using the module.

=head1 DATE TYPE SUPPORT

The latest 0.79 version of Storable::AMF added basic date support with the new_date() and perl_date() utilitiy functions. This is just great. Internally an AMF Date Type represents a timestamp in milliseconds since the epoch in UTC ("neutral") timezo...

lib/AMF/Connection.pm  view on Meta::CPAN

my $client = new AMF::Connection ( ... );

# ... prepare parameters...

my $searchAMFObject = bless( {
                   'searchId' => $searchId,
                   'startHit' => int($startHit),
                   'searchString' => $searchString,
                   'hitsPerPage' => ($hitsPerPage) ? int($hitsPerPage) : 20,
                   'sortId' => $sortId,
       }, 'com.mycompany.application.flex.data.SearchQueryFx');

my $response = $client->call( "MySearchSevice.searchAdvanced", [ $searchAMFObject ] );

#....

For other Java to ActionScript type mappings possibilities see http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/ActionMessageOutput.html#writeObject(java.lang.Object)

For PHP gateways at the moment there is not a known/documented way to map client to server objects.

Future versions of AMF::Connection may add a proper configurable factory for application specific ActionScript/Flex object mappings.

lib/AMF/Connection.pm  view on Meta::CPAN

=head1 SEE ALSO

 AMF::Connection::MessageBody
 Storable::AMF, Storable::AMF0, LWP::UserAgent

 Flex messaging framework / LiveCycle Data Services
  http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/client/package-summary.html
  http://livedocs.adobe.com/blazeds/1/javadoc/flex/messaging/io/amf/client/AMFConnection.html
  http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/NetConnection.html
  http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing/lcds31_using.pdf
  http://help.adobe.com/en_US/Flex/4.0/AccessingData/flex_4_accessingdata.pdf
  http://www.adobe.com/support/documentation/en/livecycledataservices/documentation.html
 
 Specifications
  http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf (AMF0)
  http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf (AMF3)

 SabreAMF
  http://code.google.com/p/sabreamf/

=head1 AUTHOR

lib/AMF/Connection/InputStream.pm  view on Meta::CPAN


	return bless($self, $class);
	};

sub readBuffer {
	my ($class, $length) = @_;

	croak "Buffer underrun at position: ". $class->{'cursor'} . ". Trying to fetch ". $length . " bytes from buffer total length ".length($class->{'stream'})
		if($length + $class->{'cursor'} > length($class->{'stream'}));

        my $data = substr($class->{'stream'},$class->{'cursor'},$length);
	$class->{'cursor'}+=$length;
	
	return $data;
	};

sub readByte {
	my ($class) = @_;

	return ord($class->readBuffer(1));
	};

sub readInt {
	my ($class) = @_;

lib/AMF/Connection/InputStream.pm  view on Meta::CPAN

		    || not defined $class->{'options'})
		  {
        	    ($obj, $len) = Storable::AMF0::deparse_amf( substr($class->{'stream'},$class->{'cursor'}));
		  }
		else
		  {
        	    ($obj, $len) = Storable::AMF0::deparse_amf( substr($class->{'stream'},$class->{'cursor'}), $class->{'options'});
		  }
		};

	croak "Can not read AMF".$encoding." data starting from position ".$class->{'cursor'}." of input - reason: ".$@ ."\n"
		if($@);

	if(defined $obj) {
		$class->{'cursor'}+=$len
			unless( $len + $class->{'cursor'} > length($class->{'stream'}) );	
		};

	return $obj;
	};

lib/AMF/Connection/MessageBody.pm  view on Meta::CPAN

package AMF::Connection::MessageBody;

use strict;
use Carp;

sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my ($target,$response,$data) = @_;
	
	my $self = {
		'target' => $target,
		'response' => $response,
		'data' => $data # we might want to have some kind of mapper between remote objects and local / user registered ones
		};

	return bless($self, $class);
	};

sub setTarget {
	my ($class, $target) = @_;

	$class->{'target'} = $target;
	};

lib/AMF/Connection/MessageBody.pm  view on Meta::CPAN

	$class->{'response'} = $response;
	};

sub getResponse {
	my ($class) = @_;

	return $class->{'response'};
	};

sub setData {
	my ($class, $data) = @_;

	$class->{'data'} = $data;
	};

sub getData {
	my ($class) = @_;

	return $class->{'data'};
	};

# HTTP::Response-ish methods ...

sub is_error {
	my ($class) = @_;

	return ($class->{'target'} =~ m|onStatus|) ? 1 : 0 ;
	};

lib/AMF/Connection/OutputStream.pm  view on Meta::CPAN

	};

sub getStreamData {
	my ($class) = @_;
	
	return $class->{'stream'};
	};

# wrtie an AMF entity
sub writeAMFData {
        my ($class,$encoding,$data) = @_;

	local $@ = undef;

	my $bytes;
        if($encoding == 3 ) {
		if ($storable_with_options  == 0
		    || not defined $class->{'options'})
                  {
		    $bytes = Storable::AMF3::freeze($data);
		  }
		else
		  {
		    $bytes = Storable::AMF3::freeze($data, $class->{'options'});
		  }
		$class->writeByte(0x11);
        } else {
		if ($storable_with_options  == 0
		    || not defined $class->{'options'})
                  {
		    $bytes = Storable::AMF0::freeze($data);
		  }
		else
		  {
		    $bytes = Storable::AMF0::freeze($data, $class->{'options'});
		  }
                };

	croak "Can not write AMF".$encoding." data starting from position ".$class->{'cursor'}." of input - reason: ".$@ ."\n"
		if($@);

	$class->writeBuffer($bytes);
        };

1;
__END__

=head1 NAME



( run in 0.379 second using v1.01-cache-2.11-cpan-8d75d55dd25 )