package TestServer;
use warnings;
use strict;
use POE;
use POE::Component::Server::TCP;
use Socket qw(sockaddr_in);
my %clients;
my %servers;
my $seq = 0;
sub spawn {
my ($class, $port) = @_;
my $alias = 'TestServer_' . ++$seq;
POE::Component::Server::TCP->new(
Alias => $alias,
Port => $port, # Random one if 0.
Address => "127.0.0.1",
ClientInput => \&discard_client_input,
ClientConnected => \®ister_client,
ClientDisconnected => \&unregister_client,
Started => sub {
# Switch $port to the port this server actually bound on.
my $listener_sockname = $_[HEAP]{listener}->getsockname();
if (defined $listener_sockname) {
($port, undef) = sockaddr_in($listener_sockname);
}
else {
$port = undef;
}
},
InlineStates => {
send_something => \&internal_send_something,
},
);
$servers{$port} = $alias;
return $port;
}
sub register_client {
$clients{$_[SESSION]->ID} = 1;
}
sub unregister_client {
delete $clients{$_[SESSION]->ID};
}
sub discard_client_input {
# Do nothing.
}
sub send_something {
foreach my $client (keys %clients) {
$poe_kernel->call($client, "send_something");
}
}
sub internal_send_something {
$_[HEAP]->{client}->put(scalar localtime);
}
sub shutdown {
foreach my $alias (values(%servers), keys(%clients)) {
$poe_kernel->post($alias => "shutdown");
}
}
sub shutdown_clients {
foreach my $session (keys(%clients)) {
$poe_kernel->call($session => "shutdown");
}
}
1;