How does one force PoCo-Server-TCP to flush?
With Fletch's blessing, I have adapted POE-Component-SOAP to use
POE-Component-Server-TCP. However, I am seeing some strange socket
behavior that causes the SOAP server to fail sporadically, which I
believe is related to output buffer flushing. I am hoping some of you
could shed some light on the subject.
Included at the end of the message is the actual code. It is very
short. Kudos to POE-Component-Server-TCP which makes this very easy.
Specifically, what I am seeing is the following packet sequence from
SOAP::Lite reference implementation:
client -> server SYN
server -> client SYN, ACK
client -> server ACK
client -> server PSH, ACK # send SOAP request
server -> client ACK
client -> server FIN, ACK # indicating request transmission completed
server -> client ACK
server -> client PSH, ACK # send SOAP response
client -> server ACK
server -> client FIN, ACK # indicating response transmission completed
client -> server ACK
The POE implemenation produces slightly different sequences.
Cases when the response was sent and received by the client:
client -> server SYN
server -> client SYN, ACK
client -> server ACK
client -> server PSH, ACK # send SOAP request
server -> client ACK
server -> client PSH, ACK # send SOAP response
client -> server ACK
client -> server FIN, ACK
server -> client FIN, ACK
client -> server ACK
Cases when the response was written, but never transmitted:
client -> server SYN
server -> client SYN, ACK
client -> server ACK
client -> server PSH, ACK # send SOAP request
server -> client ACK
client -> server FIN, ACK
server -> client FIN, ACK
client -> server ACK
The debug messages indicated the responses were successfully transmitted
whenever a ClientFlushed event occurs. The reference implementation of
SOAP::Lite seems to close the socket after each response which forces
the buffer to be flushed. Is there some way to accomplish this with
PoCo-Server-TCP?
Pete
----
######################################################################
#
# A POE TCP SOAP Server Component
#
# $Id$
#
# Author: Peter Chen <[EMAIL PROTECTED]>
# Date: 7/10/2002
#
# See Documentation at the end of the file.
#
########################################################################
########################################################################
#
# Module Headers (use, require, our variables)
package POE::Component::SOAP::TCP::Server;
use strict;
use warnings;
use Carp qw( croak carp );
use Socket qw(INADDR_LOOPBACK);
use POE;
use POE::Component::Server::TCP;
#use SOAP::Lite +trace => qw(dispatch trace debug);
use SOAP::Lite;
use constant ALIAS_DEFAULT => 'SOAP';
use constant ADDRESS_DEFAULT => '127.0.0.1';
our $VERSION = 0.50;
# End of Module Headers
#
########################################################################
########################################################################
#
# Object Methods
# Alias =>
# Address =>
# Port =>
# Dispatch =>
# Debug =>
# Error =>
# ClientError =>
sub new {
my $type = shift;
my $mi = $type . '->new()';
croak "$mi requires an even number of parameters" if (@_ & 1);
my %param = @_;
my $alias = delete $param{Alias} || ALIAS_DEFAULT;
my $address = delete $param{Address} || ADDRESS_DEFAULT;
my $debug = delete $param{Debug} || 0;
my $error = delete $param{Error};
my $clienterror= delete $param{ClientError};
foreach ( qw(Port Dispatch) ) {
croak "$mi requires a $_ parameter"
unless (exists $param{$_} && defined $param{$_});
}
my $port = delete $param{Port};
my $dispatch = delete $param{Dispatch};
croak "$mi: Dispatch must be a arrayref"
unless (ref($dispatch) eq 'ARRAY');
print STDERR "$mi: starting soap server, alias $alias, on $address:$port\n"
if $debug;
POE::Component::Server::TCP->new
(
Alias => $alias,
Port => $port,
Address => $address,
Error => $error,
ClientError => $clienterror,
ClientFilter => [ 'POE::Filter::Line',
InputLiteral => '</SOAP-ENV:Envelope>',
OutputLiteral => "\n\n",
],
ClientInput => sub {
my( $heap, $input, $wheel_id ) = @_[ HEAP, ARG0, ARG1 ];
print STDERR "\n%got input $input%\n\n" if $debug;
$heap->{_dispatch} = SOAP::Server->new( )->dispatch_to( @{ $dispatch
} );
$input .= '</SOAP-ENV:Envelope>';
print STDERR "request:\n%$input%\n" if $debug;
my $response = $heap->{_dispatch}->handle( $input );
print STDERR "response:\n%$response%\n" if $debug;
$heap->{client}->put( $response );
},
ClientFlushed => sub {
my( $kernel, $heap, $wheel_id ) = @_[ KERNEL, HEAP, ARG0 ];
print STDERR "POE::Component::SOAP::TCP::Server::Handler flushed\n"
if $debug;
$kernel->yield('shutdown');
},
);
}
# End of Object Methods
#
########################################################################
1;
__END__