NAME

Reflexive::Role::TCPServer - Provides a consumable Reflex-based multiplexing TCP server behavior

VERSION

version 1.121580

SYNOPSIS

{
    package MyTCPServer;
    use Moose;
    use MooseX::Types::Moose(':all');
    use MooseX::Types::Structured(':all');
    use MooseX::Params::Validate;

    extends 'Reflex::Base';

    sub on_socket_data
    {
        my ($self, $args) = pos_validated_list
        (
            \@_,
            { isa => 'MyTCPServer' },
            { isa => 'Reflexive::Event::Data' },
        );
        my $data = $args->data;
        my $socket = $args->get_first_emitter();
        warn "Received data ($data) from socket ($socket)";
        chomp($data);
        # look at Reflex::Role::Streaming for what methods are available
        $socket->put(reverse($data)."\n");
    }

    with 'Reflexive::Role::TCPServer';
}

my $server = MyTCPServer->new();
$server->run_all();

DESCRIPTION

Reflexive::Role::TCPServer provides a multiplexing TCP server behavior for consuming classes. It does this by being an amalgamation of other Reflex and Reflexive roles such as Reflex::Role::Accepting and Reflexive::Role::Collective. The only required method to be implemented by the consumer is "on_socket_data" which is called when sockets receive data.

See the eg directory in the shipped distribution for an example that is more detailed than the synopsis.

ROLE_PARAMETERS

input_filter_class

This is the name of the class to use when constructing an input filter for each socket that is accepted. It defaults to POE::Filter::Stream.

Please see Reflexive::Stream::Filtering for more information on how filtering occurs on data.

input_filter_args

If the input filter class takes any arguments during construction, put them here as a HashRef

output_filter_class

This is the name of the class to use when constructing an output filter for each socket that is accepted. It defaults to POE::Filter::Stream.

Please see Reflexive::Stream::Filtering for more information on how filtering occurs on data.

output_filter_args

If the output filter class takes any arguments during construction, put them here as a HashRef

ROLE_REQUIRES

on_socket_data

Dict[data => Any, _sender => Object]

This role requires the method on_socket_data to be implemented in the consuming class prior to application. The inbound, filtered data will be available in the HashRef under the key 'data'. The socket that generated the event will be available via "get_first_emitter" in Reflex::Sender on the _sender object.

PUBLIC_ATTRIBUTES

port

is: ro, isa: Int, default: 5000, writer: _set_port

port holds the particular TCP port number to use when listening for connections. It defaults to 5000 for no real particular reason, other than to make it easier to use this role in the PSGI space.

host

is: ro, isa: Str, default: '0.0.0.0', writer: _set_host

host holds the address to use when setting up the listening socket. It defaults to 0.0.0.0 (which means all available interfaces/addresses).

PROTECTED_ATTRIBUTES

listener

is: ro, isa: FileHandle, lazy: 1
clearer:    clear_listener
predicate:  has_listener
builder:    _build_listener

listener holds the listening socket from which to accept connections. Ideally, this attribute shouldn't be touched in consuming classes

listener_active

is: ro, isa: Bool, default: 1

listener_active determines the default state of the listener socket upon creation of the object. It defaults to true which means that when the object is built and handed off to POE, it will immediately select() over it. If this behavior is not desired, simply set this to false at construction.

sockets

is: ro, isa: HashRef, traits: Hash
clearer: _clear_sockets
handles:
        '_set_socket'       => 'set',
        '_delete_socket'    => 'delete',
        '_count_sockets'    => 'count',
        '_all_sockets'      => 'values',

sockets stores the complete, accepted connections from clients.

sockets is really only for low-level access and the facilities from the consumed Reflexive::Role::Collective should be used to store/remove clients.

PUBLIC_METHODS

try_listener_build

try_listener_build is the method called when the object is first instantiated to attempt to bind a listening socket. It wraps construction of the "listener" attribute inside a try/catch block. If it fails the "on_listener_error" callback is fired to allow for retrying the binding.

shutdown

shutdown will stop the listening socket forcibly stop all active sockets.

This will allow the event loop to terminate.

PROTECTED_METHODS

_build_listener

_build_listener takes the "host" and "port" attributes and builds a listening socket using IO::Socket::INET. If it is unable to bind to the host/port combination, it will confess.

_build_socket

(FileHandle)

_build_socket is called when the listener_accept event fires. The raw socket, and the filters constructed from the "input_filter_class" and "output_filter_class" parameters are passed to the constructor for Reflexive::Stream::Filtering and returned.

BUILD

BUILD is advised in a couple of different ways to ensure proper operation:

1) before BUILD is used to attempt to build the listener socket prior to Reflex::Role::Readable attempts to use the socket. This allows for the capture of exceptions on binding if they occur.

2) after BUILD is used to watch the events that this role emits.

on_listener_accept

(Reflex::Event::Socket)

on_listener_accept is the callback method called when a socket connection has been accepted. It calls "_build_socket" and stores the result using "remember" in Reflexive::Role::Collective which is named "store_socket" in this role.

on_listener_error

(Reflex::Event::Error)

on_listener_error is the callback called when there is an error on the listening socket.

on_socket_stop

(Reflex::Event)

on_socket_stop is the callback method fired when sockets close. It calls "forget" in Reflexive::Role::Collective, which is named "remove_socket" in this role, to no longer store the socket. The socket that sent the event will be the first emitter.

on_socket_error

(Reflex::Event::Error)

on_socket_error is the callback fired when a socket encounters an error. The socket that sent the event will be the first emitter. This method merely unstores the socket.

AUTHOR

Nicholas R. Perez <nperez@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Nicholas R. Perez <nperez@cpan.org>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.