Hi - I'm new to POE and this is my first post here. Getting straight to the point, my application starts a service which listens on port 31008. Clients connect and send integers at random intervals. Everytime a client sends an integer, I increment two counters, one called 'actual' and one called 'register'. Every 3 seconds I remove the count from 'register' and push it onto an array for later processing. The 'actual' counter continuously increments.

Everything works fine, except that when the client exits, its session doesn't terminate. I suspect this is because of the way I am handling the timer. I start the timer in 'child_start' event and the timer calls the 'flush_register' event. Inside the 'flush_register' event, I do what I need and then restart the timer again. This way, the timer is on a continuous 3-second interval.

Below is the Perl program, followed by the output from a sample run. When looking at the sample output, be aware that the client exits at 15:31:15, the timer continues beyond this time, and I CTRL-C the server at 15:31:21. I'm basically stuck in a loop I presume because a reference to the session still exists?

What I would really like is for the timer to no longer work once the child exits. However, 'child_stop' doesn't appear to execute until I CTRL-C the server, not when the child exits. I tried $poe_kernel->alarm_remove_all() in 'child_stop' but of course that didn't change anything.

Any advice to help steer me in the correct general direction would be greatly appreciated.

With my thanks,
David

#!/usr/bin/perl -w

use strict;

use Socket qw(inet_ntoa);
use Time::HiRes;
use POE qw(Wheel::SocketFactory  Wheel::ReadWrite
           Filter::Line          Driver::SysRW);

use constant PORT => 31008;


POE::Session->create ( inline_states => { _start => \&server_start, _stop => \&server_stop, accept_new_client => \&accept_new_client, accept_failed => \&accept_failed, child_input => \&child_input, child_error => \&child_error } );

$poe_kernel->run();


############### # SUBROUTINES # ####################################################################### sub server_start { $_[HEAP]->{listener} = new POE::Wheel::SocketFactory ( BindPort => PORT, Reuse => 'on', SuccessEvent => 'accept_new_client', FailureEvent => 'accept_failed' );

    print "SERVER: Started listening on port ", PORT, ".\n";
}

sub flush_register {
    my $heap = $_[HEAP];
    my $session_id = $_[SESSION]->ID;

    my $register = $heap->{register};
    push @{ $heap->{conveyor} }, $register;
    $heap->{register} -= $register;

    print scalar(localtime()), " Removed $register from register ",
        "$session_id.\n";

    # Renew the timer that moves from register to conveyor every 3 sec
    $_[KERNEL]->delay_set(flush_register => 3);
}

sub accept_new_client {
    my ($socket, $peeraddr, $peerport) = @_[ARG0 .. ARG2];
    $peeraddr = inet_ntoa($peeraddr);

    POE::Session->create (
        inline_states => {
            _start         => \&child_start,
            _stop          => \&child_stop,
            flush_register => \&flush_register
        },
        package_states => [
            main   => [ 'child_input', 'child_done', 'child_error' ]
        ],
        args => [ $socket, $peeraddr, $peerport ]
    );

    print "SERVER: Got connection from $peeraddr:$peerport.\n";
}

sub child_input {
    my $data = $_[ARG0];
    my $heap = $_[HEAP];

    unless ($data =~ /^\d{1,10}$/) {
        print "SERVER: Got bad data from child: [$data]\n";
        return;
    }

my $session_id = $_[SESSION]->ID;

    $heap->{actual}   += $data;
    $heap->{register} += $data;

    print scalar(localtime()),
        " CHILD: Got input from peer $session_id: ",
        "\"$data\" ($heap->{register}).\n";
}

sub child_start {
    my ($heap, $socket)  = @_[HEAP, ARG0];

    $heap->{readwrite} = new POE::Wheel::ReadWrite (
        Handle => $socket,
        Driver => new POE::Driver::SysRW (),
        Filter => new POE::Filter::Line (),
        InputEvent => 'child_input',
        ErrorEvent => 'child_error'
    );

    $heap->{readwrite}->put('Hello, client!');
    $heap->{peername} = join ':', @_[ARG1, ARG2];
    print "CHILD: Connected to $heap->{peername}.\n";

    $heap->{actual}   = 0;
    $heap->{register} = 0;

$heap->{conveyor} = [];

    # Start a timer that moves from register to conveyor every 3 seconds
    $_[KERNEL]->delay_set(flush_register => 3);
}

sub child_stop {
my $heap = $_[HEAP];
print "CHILD: Stopped.\n";
print "Totals: Actual: $heap->{actual}, Register: $heap->{register}.\n";
}


sub child_done {
    delete $_[HEAP]->{readwrite};
    print "CHILD: Disconnected from ", $_[HEAP]->{peername}, ".\n";
}

sub child_error {
    my ($function, $error) = @_[ARG0, ARG2];
    delete $_[HEAP]->{readwrite};
    print "CHILD: call to $function() failed: $error.\n" if $error;
}

sub accept_failed {
    my ($function, $error) = @_[ARG0, ARG2];

    delete $_[HEAP]->{listener};
    print "SERVER: Call to $function() failed: $error.\n";
}

sub server_stop {
    print "SERVER: Stopped.\n";
}

SAMPLE OUTPUT:

SERVER: Started listening on port 31008.
CHILD: Connected to 127.0.0.1:51687.
SERVER: Got connection from 127.0.0.1:51687.
Thu Jun  5 15:31:06 2003 CHILD: Got input from peer 3: "9" (9).
Thu Jun  5 15:31:06 2003 CHILD: Got input from peer 3: "10" (19).
Thu Jun  5 15:31:07 2003 CHILD: Got input from peer 3: "6" (25).
Thu Jun  5 15:31:08 2003 CHILD: Got input from peer 3: "2" (27).
Thu Jun  5 15:31:08 2003 CHILD: Got input from peer 3: "7" (34).
Thu Jun  5 15:31:09 2003 Removed 34 from register 3.
Thu Jun  5 15:31:09 2003 CHILD: Got input from peer 3: "9" (9).
Thu Jun  5 15:31:10 2003 CHILD: Got input from peer 3: "3" (12).
Thu Jun  5 15:31:10 2003 CHILD: Got input from peer 3: "1" (13).
Thu Jun  5 15:31:11 2003 CHILD: Got input from peer 3: "5" (18).
Thu Jun  5 15:31:11 2003 CHILD: Got input from peer 3: "7" (25).
Thu Jun  5 15:31:12 2003 Removed 25 from register 3.
Thu Jun  5 15:31:12 2003 CHILD: Got input from peer 3: "9" (9).
Thu Jun  5 15:31:13 2003 CHILD: Got input from peer 3: "5" (14).
Thu Jun  5 15:31:14 2003 CHILD: Got input from peer 3: "8" (22).
Thu Jun  5 15:31:14 2003 CHILD: Got input from peer 3: "8" (30).
Thu Jun  5 15:31:15 2003 Removed 30 from register 3.
Thu Jun  5 15:31:18 2003 Removed 0 from register 3.
Thu Jun  5 15:31:21 2003 Removed 0 from register 3.
^CCHILD: Stopped.
Totals: Actual: 89, Register: 0.
SERVER: Stopped.



Reply via email to