Matt Sergeant wrote:

On 29-Nov-07, at 4:55 AM, JD wrote:

Thus far I have the Net::Server and it returning xml.
What I haven't got is the continuation stuff. I can probably hack at
it and eventually get it to work, but I'd rather hack in the right
direction from the get go.


OK, so your best start at this is to create a stand-alone app using Danga::Socket first. This will give you some experience of how that framework works...

So create a subclass of Danga::Socket, instantiate your instance, and call Danga::Socket->EventLoop to run the event loop.

Get everything working that way, then we can talk about continuations.


Done all that. Have cobbled an app together (1 screen) and it works!
Below is the code. I seem to be holding a lot of circular references.
Should I be using weaken somewhere? (I've never used it)

The plugin:
*
use Firstb2b::Acme;
use Data::Dumper;
use Storable qw( freeze thaw );

sub init {
&{$Firstb2b::Acme::subref};
}

sub register {
my $self = shift;
$self->register_hook('xmlresponse' => 'hook_xmlresponse1');
$self->register_hook('xmlresponse' => 'hook_xmlresponse2');
}

sub hook_xmlresponse2 {
my ($self, $input) = @_;
$self->log(LOGDEBUG, "\n\nXMLRESPONSE 2-> ".$self->client->notes('xml_response'));
if ($self->client->notes('xml_response') == OK) {
my $rpc = $self->client->notes('rpc');

my $parser = XML::LibXML->new();
my $dom = $parser->parse_string( $rpc->{data}{xml} );
$input->dom( $dom );

my $styles = $rpc->{data}{styles};
print Dumper($styles);
my $dir = $self->config('StyleSheetDir').'/';
my $out = $input->transform(map XSLT( $dir.$_->{style}, %{$_->{params}} ), @{$styles});

return OK, $out;
}
return $self->client->notes('xml_response');
}

sub hook_xmlresponse1 {

my ($self, $input) = @_;
my ( $dom, $sub, $bl, $uri );
my $client = $self->client;

$client->notes('xml_response', DECLINED);

if ( $client->headers_in->filename =~ /\.(?i:png|gif|css|jpg|js|html)$/ ) {
$self->log(LOGDEBUG, 'Declined: '. $client->headers_in->filename);
return DECLINED;
}
$bl = Firstb2b::Acme->new( $self );
$sub = 'state_'.$bl->get_state;
$bl->$sub;

return CONTINUATION;

} # hook_xmlresponse1


package Firstb2b::Acme;

use fields (
'plugin', # The axkit2 plugin ref
);

sub new {
my Firstb2b::Acme $self = shift;
my $plugin = shift;
unless ( ref $self ) { $self = fields::new( $self ) }
$self->{plugin} = $plugin;
$cache = $plugin->cache;
return $self;
} # new

sub create_rpc {
my Firstb2b::Acme $self = shift;
my $PORT = 2000;
my $sock = IO::Socket::INET->new( PeerHost => 'localhost',
PeerPort => $PORT,
Proto => 'tcp',
Type => SOCK_STREAM,
Blocking => 0 )
or die "Error creating client on port $PORT : [EMAIL PROTECTED]";
IO::Handle::blocking( $sock, 0 );
my $rpc = Firstb2b::AxKit2::SubprocessEvent->new($sock, $self->{plugin}->client);
$self->{plugin}->client->notes( 'rpc', $rpc );
$rpc->watch_read(1);
$rpc->AddOtherFds( fileno($sock) => sub{} );
return $rpc;
}

sub state_login {
my Firstb2b::Acme $self = shift;

$self->{plugin}->log(LOGDEBUG, "\n\n_STATE_LOGIN\n\n");

my $rpc = $self->create_rpc;
my $params = { method => 'state_login' };
$rpc->write( freeze( $params ) . 'ROSE' . EOL );
return 1;
}

package Firstb2b::AxKit2::SubprocessEvent;

use AxKit2::Constants;
use base qw(Danga::Socket);
use fields qw(data client);
use Storable qw( freeze thaw );

sub new {
my Firstb2b::AxKit2::SubprocessEvent $self = shift;
my $sock = shift;
my $client = shift;
$self = fields::new( $self ) unless ref($self);
$self->SUPER::new($sock);
$self->{data} = '';
$self->{client} = $client;
return $self;
}

sub event_read {
my Firstb2b::AxKit2::SubprocessEvent $self = shift;
my $bref = $self->read(10000);
return $self->close($!) unless defined $bref;
chomp $$bref; # lose the \n
my $finished = $$bref =~ s/ROSE\015?//;
$self->{data} .= $$bref;

if ( $finished ) {
$self->{data} = thaw $self->{data};
$self->{client}->notes('xml_response', OK);
$self->{client}->finish_continuation;
}
else {
$self->{client}->notes('xml_response', DECLINED);
}
}

1;

John
*

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to