# POE::Wheel::ListenAccept - phpMan

## NAME
    [POE::Wheel::ListenAccept] - accept connections from regular listening
    sockets

## SYNOPSIS
    See "SYNOPSIS" in [POE::Wheel::SocketFactory] for a simpler version of
    this program.

      #!perl

      use warnings;
      use strict;

      use [IO::Socket];
      use POE qw([Wheel::ListenAccept] [Wheel::ReadWrite]);

      [POE::Session]->create(
        inline_states => {
          _start => sub {
            # Start the server.
            $_[HEAP]{server} = [POE::Wheel::ListenAccept]->new(
              Handle => [IO::Socket::INET]->new(
                LocalPort => 12345,
                Listen => 5,
              ),
              AcceptEvent => "on_client_accept",
              ErrorEvent => "on_server_error",
            );
          },
          on_client_accept => sub {
            # Begin interacting with the client.
            my $client_socket = $_[ARG0];
            my $io_wheel = [POE::Wheel::ReadWrite]->new(
              Handle => $client_socket,
              InputEvent => "on_client_input",
              ErrorEvent => "on_client_error",
            );
            $_[HEAP]{client}{ $io_wheel->ID() } = $io_wheel;
          },
          on_server_error => sub {
            # Shut down server.
            my ($operation, $errnum, $errstr) = @_[ARG0, ARG1, ARG2];
            warn "Server $operation error $errnum: $errstr\n";
            delete $_[HEAP]{server};
          },
          on_client_input => sub {
            # Handle client input.
            my ($input, $wheel_id) = @_[ARG0, ARG1];
            $input =~ tr[a-zA-Z][n-za-mN-ZA-M]; # ASCII rot13
            $_[HEAP]{client}{$wheel_id}->put($input);
          },
          on_client_error => sub {
            # Handle client error, including disconnect.
            my $wheel_id = $_[ARG3];
            delete $_[HEAP]{client}{$wheel_id};
          },
        }
      );

      [POE::Kernel]->run();
      exit;

## DESCRIPTION
    [POE::Wheel::ListenAccept] implements non-blocking accept() calls for
    plain old listening server sockets. The application provides the socket,
    using some normal means such as socket(), [IO::Socket::INET], or
    [IO::Socket::UNIX]. [POE::Wheel::ListenAccept] monitors the listening socket
    and emits events whenever a new client has been accepted.

    Please see [POE::Wheel::SocketFactory] if you need non-blocking connect()
    or a more featureful listen/accept solution.

    [POE::Wheel::ListenAccept] only accepts client connections. It does not
    read or write data, so it neither needs nor includes a put() method.
    [POE::Wheel::ReadWrite] generally handles the accepted client socket.

## PUBLIC METHODS
  new
    new() creates a new [POE::Wheel::ListenAccept] object for a given
    listening socket. The object will generate events relating to the socket
    for as long as it exists.

    new() accepts two required named parameters:

   Handle
    The "Handle" constructor parameter must contain a listening socket
    handle. [POE::Wheel::FollowTail] will monitor this socket and accept() new
    connections as they arrive.

   AcceptEvent
    "AcceptEvent" is a required event name that [POE::Wheel::ListenAccept]
    will emit for each accepted client socket. "PUBLIC EVENTS" describes it
    in detail

   ErrorEvent
    "ErrorEvent" is an optional event name that will be emitted whenever a
    serious problem occurs. Please see "PUBLIC EVENTS" for more details.

  event
    event() allows a session to change the events emitted by a wheel without
    destroying and re-creating the object. It accepts one or more of the
    events listed in "PUBLIC EVENTS". Undefined event names disable those
    events.

    Ignore connections:

      sub ignore_new_connections {
        $_[HEAP]{tailor}->event( AcceptEvent => "on_ignored_accept" );
      }

      sub handle_ignored_accept {
        # does nothing
      }

  ID
    The ID() method returns the wheel's unique ID. It's useful for storing
    the wheel in a hash. All [POE::Wheel] events should be accompanied by a
    wheel ID, which allows the wheel to be referenced in their event
    handlers.

      sub setup_listener {
        my $wheel = [POE::Wheel::ListenAccept]->new(... etc  ...);
        $_[HEAP]{listeners}{$wheel->ID} = $wheel;
      }

## PUBLIC EVENTS
    [POE::Wheel::ListenAccept] emits a couple events.

  AcceptEvent
    "AcceptEvent" names the event that will be emitted for each newly
    accepted client socket. It is accompanied by three parameters:

    $_[ARG0] contains the newly accepted client socket handle. It's up to
    the application to do something with this socket. Most use cases involve
    passing the socket to a [POE::Wheel::ReadWrite] constructor.

    $_[ARG1] contains the accept() call's return value, which is often the
    encoded remote end of the remote end of the socket.

    $_[ARG2] contains the [POE::Wheel::ListenAccept] object's unique ID. This
    is the same value as returned by the wheel's ID() method.

    A sample "AcceptEvent" handler:

      sub accept_state {
        my ($client_socket, $remote_addr, $wheel_id) = @_[ARG0..ARG2];

        # Make the remote address human readable.
        my ($port, $packed_ip) = sockaddr_in($remote_addr);
        my $dotted_quad = inet_ntoa($packed_ip);

        print(
          "Wheel $wheel_id accepted a connection from ",
          "$dotted_quad port $port.\n"
        );

        # Spawn off a session to interact with the socket.
        create_server_session($handle);
      }

  ErrorEvent
    "ErrorEvent" names the event that will be generated whenever a new
    connection could not be successfully accepted. This event is accompanied
    by four parameters:

    $_[ARG0] contains the name of the operation that failed. This usually is
    'accept', but be aware that it's not necessarily a function name.

    $_[ARG1] and $_[ARG2] hold the numeric and stringified values of $!,
    respectively. [POE::Wheel::ListenAccept] knows how to handle EAGAIN (and
    system-dependent equivalents), so this error will never be returned.

    $_[ARG3] contains the wheel's unique ID, which may be useful for
    shutting down one particular wheel out of a group of them.

    A sample "ErrorEvent" event handler. This assumes the wheels are saved
    as in the "ID" example.

      sub error_state {
        my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
        warn "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
        delete $_[HEAP]{listeners}{$wheel_id};
      }

## SEE ALSO
    [POE::Wheel] describes the basic operations of all wheels in more depth.
    You need to know this.

    [POE::Wheel::ReadWrite] for one possible way to handle clients once you
    have their sockets.

    The SEE ALSO section in POE contains a table of contents covering the
    entire POE distribution.

## BUGS
    None known.

AUTHORS & COPYRIGHTS
    Please see POE for more information about authors and contributors.

