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;