Perl POE - How to properly yielding a timer

327 Views Asked by At

I'm trying to get along with POE in perl. Very slowly I'm starting to grasp its concept but I'm far from really understanding it:

#!perl

use warnings;
use strict;

use IO::Socket;
use POE qw(Wheel::SocketFactory Wheel::ReadWrite);

my $SERVER_ADDR = '192.168.178.6';
my $SERVER_PORT = '50099';


POE::Session->create(
    inline_states => {
        _start => sub {
            # Start the server.
            $_[HEAP]{server} = POE::Wheel::SocketFactory->new(
                RemoteAddress  => $SERVER_ADDR,
                RemotePort     => $SERVER_PORT,
                SocketProtocol => 'udp',
                SuccessEvent   => "on_connect",
                FailureEvent   => "on_server_error",
            );
        },
        on_connect => sub {
            # Begin interacting with the server.
            my $client_socket = $_[ARG0];
            my $io_wheel      = POE::Wheel::ReadWrite->new(
                Handle     => $client_socket,
                InputEvent => "on_recieve_data",
                ErrorEvent => "on_connect_error",
            );
            $_[HEAP]{client}{ $io_wheel->ID() } = $io_wheel;

            $io_wheel->put( "login monitor monitor", "log on", );
        },

        on_server_error => sub {
            # Shut down server.
            my ( $operation, $errnum, $errstr ) = @_[ ARG0, ARG1, ARG2 ];
            warn "Server $operation error $errnum: $errstr\n";
            delete $_[HEAP]{server};
        },
        on_recieve_data => sub {
            # Handle client input.
            my ( $kernel, $input, $wheel_id ) = @_[ KERNEL, ARG0, ARG1 ];
            print "Received: $input\n";

            $kernel->yield('keepalive');
        },
        on_connect_error => sub {
            # Handle client error, including disconnect.
            my $wheel_id = $_[ARG3];
            delete $_[HEAP]{client}{$wheel_id};
        },
        keepalive => sub {
            my ( $kernel, $input, $wheel_id, $io_wheel ) = @_[ KERNEL, ARG0, ARG1, ARG2 ];
            $kernel->delay_add( keepalive => 10 );
            $io_wheel->put( "keepalive" );
        },
    }
);

POE::Kernel->run();
exit;

With this code I'm connecting to an UDP server application and read its status messages. Sofar it works with the exception of the

        keepalive => sub { ...

where I'm trying to add an timer that sends a keepalive package every 10 seconds.

How do I properly set such a timer and what is the best place to call it? I guess I'm messing up the back reference to the ReadWrite wheel but this connection between wheels/events etc is still something I'm struggling hard with. Any help and insight on this is greatly appreciated.

0

There are 0 best solutions below