Current File : //usr/local/share/man/man3/POE::Wheel::ListenAccept.3pm
.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings.  \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote.  \*(C+ will
.\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
.\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
.    ds -- \(*W-
.    ds PI pi
.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
.    ds L" ""
.    ds R" ""
.    ds C` ""
.    ds C' ""
'br\}
.el\{\
.    ds -- \|\(em\|
.    ds PI \(*p
.    ds L" ``
.    ds R" ''
.    ds C`
.    ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el       .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD.  Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
.    if \nF \{\
.        de IX
.        tm Index:\\$1\t\\n%\t"\\$2"
..
.        if !\nF==2 \{\
.            nr % 0
.            nr F 2
.        \}
.    \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "POE::Wheel::ListenAccept 3"
.TH POE::Wheel::ListenAccept 3 "2022-03-23" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
POE::Wheel::ListenAccept \- accept connections from regular listening sockets
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
See \*(L"\s-1SYNOPSIS\*(R"\s0 in POE::Wheel::SocketFactory for a simpler version of
this program.
.PP
.Vb 1
\&  #!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\en";
\&        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;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
POE::Wheel::ListenAccept implements non-blocking \fBaccept()\fR calls for
plain old listening server sockets.  The application provides the
socket, using some normal means such as \fBsocket()\fR, IO::Socket::INET, or
IO::Socket::UNIX.  POE::Wheel::ListenAccept monitors the listening
socket and emits events whenever a new client has been accepted.
.PP
Please see POE::Wheel::SocketFactory if you need non-blocking
\&\fBconnect()\fR or a more featureful listen/accept solution.
.PP
POE::Wheel::ListenAccept only accepts client connections.  It does not
read or write data, so it neither needs nor includes a \fBput()\fR method.
POE::Wheel::ReadWrite generally handles the accepted client socket.
.SH "PUBLIC METHODS"
.IX Header "PUBLIC METHODS"
.SS "new"
.IX Subsection "new"
\&\fBnew()\fR 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.
.PP
\&\fBnew()\fR accepts two required named parameters:
.PP
\fIHandle\fR
.IX Subsection "Handle"
.PP
The \f(CW\*(C`Handle\*(C'\fR constructor parameter must contain a listening socket
handle.  POE::Wheel::FollowTail will monitor this socket and \fBaccept()\fR
new connections as they arrive.
.PP
\fIAcceptEvent\fR
.IX Subsection "AcceptEvent"
.PP
\&\f(CW\*(C`AcceptEvent\*(C'\fR is a required event name that POE::Wheel::ListenAccept
will emit for each accepted client socket.  \*(L"\s-1PUBLIC EVENTS\*(R"\s0
describes it in detail
.PP
\fIErrorEvent\fR
.IX Subsection "ErrorEvent"
.PP
\&\f(CW\*(C`ErrorEvent\*(C'\fR is an optional event name that will be emitted whenever
a serious problem occurs.  Please see \*(L"\s-1PUBLIC EVENTS\*(R"\s0 for more
details.
.SS "event"
.IX Subsection "event"
\&\fBevent()\fR 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 \*(L"\s-1PUBLIC EVENTS\*(R"\s0.  Undefined event names
disable those events.
.PP
Ignore connections:
.PP
.Vb 3
\&  sub ignore_new_connections {
\&    $_[HEAP]{tailor}\->event( AcceptEvent => "on_ignored_accept" );
\&  }
\&
\&  sub handle_ignored_accept {
\&    # does nothing
\&  }
.Ve
.SS "\s-1ID\s0"
.IX Subsection "ID"
The \s-1\fBID\s0()\fR method returns the wheel's unique \s-1ID.\s0  It's useful for
storing the wheel in a hash.  All POE::Wheel events should be
accompanied by a wheel \s-1ID,\s0 which allows the wheel to be referenced in
their event handlers.
.PP
.Vb 4
\&  sub setup_listener {
\&    my $wheel = POE::Wheel::ListenAccept\->new(... etc  ...);
\&    $_[HEAP]{listeners}{$wheel\->ID} = $wheel;
\&  }
.Ve
.SH "PUBLIC EVENTS"
.IX Header "PUBLIC EVENTS"
POE::Wheel::ListenAccept emits a couple events.
.SS "AcceptEvent"
.IX Subsection "AcceptEvent"
\&\f(CW\*(C`AcceptEvent\*(C'\fR names the event that will be emitted for each newly
accepted client socket.  It is accompanied by three parameters:
.PP
\&\f(CW$_[ARG0]\fR 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.
.PP
\&\f(CW$_[ARG1]\fR contains the \fBaccept()\fR call's return value, which is often
the encoded remote end of the remote end of the socket.
.PP
\&\f(CW$_[ARG2]\fR contains the POE::Wheel::ListenAccept object's unique \s-1ID.\s0
This is the same value as returned by the wheel's \s-1\fBID\s0()\fR method.
.PP
A sample \f(CW\*(C`AcceptEvent\*(C'\fR handler:
.PP
.Vb 2
\&  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.\en"
\&    );
\&
\&    # Spawn off a session to interact with the socket.
\&    create_server_session($handle);
\&  }
.Ve
.SS "ErrorEvent"
.IX Subsection "ErrorEvent"
\&\f(CW\*(C`ErrorEvent\*(C'\fR names the event that will be generated whenever a new
connection could not be successfully accepted.  This event is
accompanied by four parameters:
.PP
\&\f(CW$_[ARG0]\fR contains the name of the operation that failed.  This
usually is 'accept', but be aware that it's not necessarily a function
name.
.PP
\&\f(CW$_[ARG1]\fR and \f(CW$_[ARG2]\fR hold the numeric and stringified values
of \f(CW$!\fR, respectively.  POE::Wheel::ListenAccept knows how to handle
\&\s-1EAGAIN\s0 (and system-dependent equivalents), so this error will never be
returned.
.PP
\&\f(CW$_[ARG3]\fR contains the wheel's unique \s-1ID,\s0 which may be useful for
shutting down one particular wheel out of a group of them.
.PP
A sample \f(CW\*(C`ErrorEvent\*(C'\fR event handler.  This assumes the wheels are
saved as in the \*(L"\s-1ID\*(R"\s0 example.
.PP
.Vb 5
\&  sub error_state {
\&    my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
\&    warn "Wheel $wheel_id generated $operation error $errnum: $errstr\en";
\&    delete $_[HEAP]{listeners}{$wheel_id};
\&  }
.Ve
.SH "SEE ALSO"
.IX Header "SEE ALSO"
POE::Wheel describes the basic operations of all wheels in more
depth.  You need to know this.
.PP
POE::Wheel::ReadWrite for one possible way to handle clients once
you have their sockets.
.PP
The \s-1SEE ALSO\s0 section in \s-1POE\s0 contains a table of contents covering
the entire \s-1POE\s0 distribution.
.SH "BUGS"
.IX Header "BUGS"
None known.
.SH "AUTHORS & COPYRIGHTS"
.IX Header "AUTHORS & COPYRIGHTS"
Please see \s-1POE\s0 for more information about authors and contributors.