One problem with our chat server so far is that you don't know who's
talking. Real chat servers allow you to keep track of who's who by
printing the user's handle next to their responses.
If we were only doing one thing at a time, asking for a handle would
be fairly straightforward code that looks something like this:
my $new = $listen->accept;
$select->add($new);
print $new->fileno . ": connected\n";
$new->write("choose a handle> ");
$handle[$new->fileno] = $new->recv;
The problem is, we don't want the server to stop while waiting for a
new user to type in a handle. We need to save where we are, handle other
users' requests while the new user is typing, and come back when the
new user is finished. The code needs to be divided into two parts:
sub login {
my($new) = @_;
$select->add($new);
print $new->fileno . ": connected\n";
$new->write("choose a handle> ");
save_where_we_are();
}
sub get_handle {
my($socket) = @_;
$handle[$socket->fileno] = $socket->recv;
}
How can we save where we are? One way is to save a pointer to a
subroutine that contains what to do next:
$nextsub[$socket->fileno] = &get_handle;
So, we can always look in the appropriate entry in @nextsub to find out
where we left off.
Putting this all together, and using objects to keep things straight
in an extensible way, we end up with this code.
next page»