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__

Reply via email to