package MyPlexer;
use base qw(Net::Server::Multiplex);
sub mux_input {
#...code...
}
__PACKAGE__->run();
This takes some nice features of Net::Server (like the server listen socket setup, configuration file processing, safe signal handling, convenient inet style STDIN/STDOUT handling, logging features, deamonization and pid tracking, and restartability -SIGHUP) and some nice features of IO::Multiplex (automatic buffered IO and per-file-handle objects) and combines them for an easy-to-use interace.
See examples/samplechat.pl distributed with Net::Server for a simple chat server that uses several of these features.
$self->configure_hook;
$self->configure(@_);
$self->post_configure;
$self->post_configure_hook;
$self->pre_bind;
$self->bind;
if (Restarting server) {
$self->restart_open_hook();
}
$self->post_bind_hook;
$self->post_bind;
$self->pre_loop_hook;
$self->loop; # This basically just runs IO::Multiplex::loop
# For routines inside a $self->loop
# See CLIENT PROCESSING below
$self->pre_server_close_hook;
$self->post_child_cleanup_hook;
$self->server_close;
if (Restarting server) {
$self->restart_close_hook();
$self->hup_server;
# Redo process again starting with configure_hook
}
$self->{server}->{client} = Net::Server::Proto::TCP->accept(); # NOTE: Multiplexed with mux_input() below
if (check_for_dequeue seconds have passed) {
$self->run_dequeue();
}
$self->get_client_info;
$self->post_accept_hook; # Net::Server style
if ($self->allow_deny
&& $self->allow_deny_hook) {
# (Net::Server style $self->process_request() is never called.)
# A unique client specific object is created
# for all mux_* methods from this point on.
$self = __PACKAGE__->new($self, client);
$self->mux_connection; # IO::Multiplex style
for (every packet received) {
$self->mux_input; # NOTE: Multiplexed with accept() above
}
} else {
$self->request_denied_hook;
# Notice that if either allow_deny or allow_deny_hook fails, then
# new(), mux_connection(), and mux_input() will never be called.
# mux_eof() and mux_close() will still be called, but using a
# common listen socket callback object instead of a unique client
# specific object.
}
$self->mux_eof;
$self->post_process_request_hook;
$self->mux_close;
This process then loops multiplexing between the accept() for the next connection and mux_input() when input arrives to avoid blocking either one.
The loop() method of Net::Server has been overridden to run the loop routine of IO::Multiplex instead. The Net::Server methods may access the IO::Multiplex object at "$self->{mux}" if desired. The IO::Multiplex methods may access the Net::Server object at "$self->{net_server}" if desired.
The process_request() method is never used with this personality.
The other Net::Server hooks and methods should work the same.
$self->{net_server}->{mux}->set_timeout($fh, $seconds_from_now);
$fh may be either a client socket or a listen socket file descriptor within the mux. $seconds_from_now may be fractional to achieve more precise timeouts. This is used in conjunction with mux_timeout, which you should define yourself.
Example:
$self->{peerport} = $self->{net_server}->{server}->{peerport};
If you need to use the IO::Multiplex style set_timeout / mux_timeout interface, you cannot use the Net::Server style check_for_dequeue / run_dequeue interface. It will not work if the check_for_dequeue option is specified. The run_dequeue method is just a compatibility interface to comply with the Net::Server::Fork style run_dequeue but is implemented in terms of the IO::Multiplex style set_timeout and mux_timeout methods.
This package may be distributed under the terms of either the
GNU General Public License
or the
Perl Artistic License
All rights reserved.
IO::Multiplex by Bruce Keeler <bruce@gridpoint.com>.