Blame README

Packit 7ef13a
README for IO::Multiplex
Packit 7ef13a
Packit 7ef13a
IO::Multiplex is designed to take the effort out of managing
Packit 7ef13a
multiple file handles.  It is essentially a really fancy front end to
Packit 7ef13a
the C<select> system call.  In addition to maintaining the C<select>
Packit 7ef13a
loop, it buffers all input and output to/from the file handles.  It
Packit 7ef13a
can also accept incoming connections on one or more listen sockets.
Packit 7ef13a
Packit 7ef13a
It is object oriented in design, and will notify you of significant events
Packit 7ef13a
by calling methods on an object that you supply.  If you are not using
Packit 7ef13a
objects, you can simply supply __PACKAGE__ instead of an object reference.
Packit 7ef13a
Packit 7ef13a
You may have one callback object registered for each file handle, or
Packit 7ef13a
one global one.  Possibly both -- the per-file handle callback object
Packit 7ef13a
will be used instead of the global one.
Packit 7ef13a
Packit 7ef13a
Each file handle may also have a timer associated with it.  A callback
Packit 7ef13a
function is called when the timer expires.
Packit 7ef13a
Packit 7ef13a
Here's an example which implements the beginnings of a multiuser game:
Packit 7ef13a
Packit 7ef13a
    use IO::Socket;
Packit 7ef13a
    use IO::Multiplex;
Packit 7ef13a
    use Tie::RefHash;
Packit 7ef13a
    
Packit 7ef13a
    my $mux  = new IO::Multiplex;
Packit 7ef13a
Packit 7ef13a
    # Create a listening socket
Packit 7ef13a
    my $sock = new IO::Socket::INET(Proto     => 'tcp',
Packit 7ef13a
                                    LocalPort => shift || 2300,
Packit 7ef13a
                                    Listen    => 4)
Packit 7ef13a
        or die "socket: $@";
Packit 7ef13a
Packit 7ef13a
    # We use the listen method instead of the add method.
Packit 7ef13a
    $mux->listen($sock);
Packit 7ef13a
    
Packit 7ef13a
    $mux->set_callback_object(__PACKAGE__);
Packit 7ef13a
    $mux->loop;
Packit 7ef13a
    
Packit 7ef13a
    # mux_connection is called when a new connection is accepted.
Packit 7ef13a
    sub mux_connection {
Packit 7ef13a
        my $package = shift;
Packit 7ef13a
        my $mux     = shift;
Packit 7ef13a
        my $fh      = shift;
Packit 7ef13a
Packit 7ef13a
        # Construct a new player object
Packit 7ef13a
        Player->new($mux, $fh);
Packit 7ef13a
    }
Packit 7ef13a
Packit 7ef13a
    package Player;
Packit 7ef13a
Packit 7ef13a
    my %players = ();
Packit 7ef13a
Packit 7ef13a
    sub new {
Packit 7ef13a
        my $package = shift;
Packit 7ef13a
        my $self    = bless { mux  => shift,
Packit 7ef13a
                              fh   => shift } => $package;
Packit 7ef13a
Packit 7ef13a
        # Register the new player object as the callback specifically for
Packit 7ef13a
        # this file handle.
Packit 7ef13a
        $mux->set_callback_object($self, $self->{fh});
Packit 7ef13a
        print $self->{fh}
Packit 7ef13a
            "Greetings, Professor.  Would you like to play a game?\n";
Packit 7ef13a
Packit 7ef13a
        # Register this player object in the main list of players
Packit 7ef13a
        $players{$self} = $self;
Packit 7ef13a
        $mux->set_timeout($self->{fh}, 1);
Packit 7ef13a
    }
Packit 7ef13a
Packit 7ef13a
    sub players { return values %players; }
Packit 7ef13a
Packit 7ef13a
    sub mux_input {
Packit 7ef13a
        my $self = shift;
Packit 7ef13a
        shift; shift;         # These two args are boring
Packit 7ef13a
        my $input = shift;    # Scalar reference to the input
Packit 7ef13a
Packit 7ef13a
        # Process each line in the input, leaving partial lines
Packit 7ef13a
        # in the input buffer
Packit 7ef13a
        while ($$input =~ s/^(.*?\n)//) {
Packit 7ef13a
            $self->process_command($1);
Packit 7ef13a
        }
Packit 7ef13a
    }
Packit 7ef13a
Packit 7ef13a
    sub mux_close {
Packit 7ef13a
       my $self = shift;
Packit 7ef13a
Packit 7ef13a
       # Player disconnected;
Packit 7ef13a
       # [Notify other players or something...]
Packit 7ef13a
       delete $players{$self};
Packit 7ef13a
    }
Packit 7ef13a
    # This gets called every second to update player info, etc...
Packit 7ef13a
    sub mux_timeout {
Packit 7ef13a
        my $self = shift;
Packit 7ef13a
        my $mux  = shift;
Packit 7ef13a
        
Packit 7ef13a
        $self->heartbeat;
Packit 7ef13a
        $mux->set_timeout($self->{fh}, 1);
Packit 7ef13a
    }