perlquestion
Big_Chicken
Hi I have the below code from the POE site and have been playing with it to try and figure out how to get it to work just a little bit better for my needs. I am new to POE so I was wondering the following questsions: <br><br><br>
1: When you disconnect from this program without doing a proper disconnect ie: pulling your network cable from the computer, I get an error stating "can not put on undefined value at line 117". Instead of this error how can I get it to gracefully kill that connection? Could I put a "or" goto the error subroutine after the put?<br><br><br>
2: Is there any way I can change how much data POE reads at any one time dynamically so that I can play with the data and send it out to the client?<br><br><br>
Thanks for your help!<br><br><br>
<code>
#!/usr/bin/perl
use warnings;
use strict;
$|=1;
# Use POE and also the TCP server component.
use POE qw(Component::Server::TCP);
sub FEED_SERVER_PORT () { 2000 }
sub CONSUMER_SERVER_PORT () { 8008 }
# A helper to log things. You could also use POE::Component::Logger
# to direct logging to a file or syslog.
sub printlog {
my $message_string = join ( "", @_ );
my $date_string = localtime();
print "$date_string $message_string\n";
}
# A table of data consumers. Input from clients attached to the feed
# server will be broadcast to every consumer listed in this table.
my %clients;
# The feed server. Whatever is sent to this server will be broadcast
# to every consumer.
POE::Component::Server::TCP->new
( Port => FEED_SERVER_PORT,
# A server error occurred. Perform a graceless stop.
Error => sub {
my ( $syscall, $error_number, $error_message ) = @_[ ARG0 .. ARG2 ];
warn ( "Couldn't start feed server: ",
"$syscall error $error_number: $error_message"
);
},
# Log that a client has connected to the feed server.
ClientConnected => sub {
my $client_id = $_[SESSION]->ID();
printlog("Feed connection $client_id started.");
},
# Log that a client has disconnected from the feed server.
ClientDisconnected => sub {
my $client_id = $_[SESSION]->ID();
printlog("Feed connection $client_id stopped.");
},
# Broadcast all feed input to any data consumers out there. This
# posts a message to each client session, requesting that it send
# the input to its client socket.
ClientInput => sub {
my ( $kernel, $input ) = @_[ KERNEL, ARG0 ];
foreach my $client_id ( keys %clients ) {
$kernel->post( $client_id => send_message => $input );
}
},
);
# The consumer server. Every consumer connection will receive what
# was sent to each feed connection.
POE::Component::Server::TCP->new
( Port => CONSUMER_SERVER_PORT,
# A server error occurred. Perform a graceless stop.
Error => sub {
my ( $syscall, $error_number, $error_message ) = @_[ ARG0 .. ARG2 ];
warn ( "Couldn't start consumer server: ",
"$syscall error $error_number: $error_message"
);
},
# Register new connections with the clients table, and log their
# connections.
ClientConnected => sub {
my $client_id = $_[SESSION]->ID();
$clients{$client_id} = "alive";
printlog("Consuming connection $client_id started.");
},
# Remove departing connections from the clients table, and log
# their disconnections.
ClientDisconnected => sub {
my $client_id = $_[SESSION]->ID();
delete $clients{$client_id};
printlog("Consuming connection $client_id stopped.");
},
# Ignore client input. Data consumers cannot talk back to their
# feeds.
ClientInput => sub {
# Do nothing.
},
# Custom event handlers go here. The "send_message" event
# requests that we send something to the client.
InlineStates =>
{ send_message => sub {
my ( $heap, $message ) = @_[ HEAP, ARG0 ];
$heap->{client}->put($message);
},
},
);
# Run the servers until something stops them.
printlog( "Feed server listening on port ", FEED_SERVER_PORT );
printlog( "Consumer server listening on port ", CONSUMER_SERVER_PORT );
$poe_kernel->run();
exit 0;
</code>