Hi, how do I tell if the client has disconnected from my poe server?
Regardless if it was a clean disconnect or a <ctrl-c>?

I've tried catching it with

POE::Wheel::ReadWrite->new(...
    ErrorEvent => 'client_error');

But I don't alway get an error if the client <ctrl-c>s.  If the client shuts
down cleanly or not, I'd like to get rid of the client in my
$heap->{clients}

Thanks
Jay


use strict;
use warnings;

$|++;

package poe;

use base qw/Class::Accessor/;

__PACKAGE__->mk_accessors(qw/
                twsHost twsPort serverVersion clientID clientPort clientHost
                callback connected port retryInterval debug errorMsg
/);

use POE qw(Wheel::ReadWrite Wheel::SocketFactory Filter::Reference
Driver::SysRW);

sub new {
        my $class = shift;
        my %arg = @_;

        die "no callback provided" unless $arg{callback};

        $arg{twsPort}            ||= 7496;
        $arg{twsHost}            ||= "localhost";
        $arg{clientID}           ||= 1;
        $arg{clientPort}         ||= 11002;

        my $self = $class->SUPER::new(\%arg);

        POE::Session->create(object_states => [ $self =>
                [qw/
                        _start
                        listenerSuccess
                        listenerFailure
                        clientInput
                        client_error
                        listenerStart
                /],
        ]);

        return $self;
}

sub run {
        $poe_kernel->run();
}


sub _start {
        $_[KERNEL]->yield("listenerStart");
}

sub listenerStart {

        my ($self, $heap) = @_[OBJECT, HEAP];

        print "Starting Listener on port: ",$self->clientPort,"\n"
                if $self->debug;

        $heap->{listen_wheel} = POE::Wheel::SocketFactory->new(
                BindPort     => $self->clientPort,
                SuccessEvent => 'listenerSuccess',
                FailureEvent => 'listenerFailure',
        );

        print "Accepting Connections\n";
}

sub listenerSuccess {

        my ($self, $heap, $handle) = @_[OBJECT, HEAP, ARG0];

        my $client = POE::Wheel::ReadWrite->new(
                        Handle => $handle,
                        Filter => POE::Filter::Reference->new(),
                        Driver => POE::Driver::SysRW->new(),
                        InputEvent => 'clientInput',
                        ErrorEvent => 'client_error',
                        FlushedEvent => 'flushed_state',
        );

        $heap->{clients}->{$client->ID} = $client;

        print "Client: ",$client->ID," connected\n" if $self->debug;
}

sub listenerFailure {
        warn "Listener Failure\n";
}

sub clientInput {

        my ($kernel, $heap, $data, $clientID) = @_[KERNEL, HEAP, ARG0,
ARG1];
        $heap->{clients}{$clientID}->put($data);
}

sub client_error {
        my ($kernel, $heap, $errorstr, $error, $clientID) =
                @_[KERNEL, HEAP, ARG0, ARG1, ARG3];

        warn "Wheel Error: $errorstr\n" if $error;
        delete $heap->{clients}->{$clientID};
}

sub flushed_state {
    # Stop a wheel after all outgoing data is flushed.
    # This frees the wheel's resources, including the
    # filehandle, and closes the connection.
print "in flush\n";
    delete $_[HEAP]->{wheel}->{$_[ARG0]};
}

1;

Reply via email to