The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

UniEvent::Stream - abstract handle of a duplex communication channel

DESCRIPTION

The class shares common interface and implementation for the UniEvent::Tcp, UniEvent::Pipe and UniEvent::Tty handles.

The key feature of UniEvent::Stream that it is aimed to handle connected-oriented full-duplex messaging aka streaming, i.e., first, the connection should be established, and then traffic might flow independently in both directions.

To use SSL with a stream, the use_ssl() method should be invoked first, before binding/listening (for server) or before connecting (for client).

It is inherited from UniEvent::Handle.

METHODS

All methods of UniEvent::Handle also apply.

listen([$backlog = 128])

listen([$callback], [$backlog = 128])

Start listening for incoming connections (stream becomes a server). $backlog indicates the number of connections the kernel might queue. If $callback is present, it is added as connection_event()->add($cb)

May return error

listening()

Returns true if stream is listening for connections.

connection_factory($callback)

Allows for setting callback which will be called by server handle when new connection is accepted. This callback is expected to return a stream handle object which will represent a client connection. This object must be of appropriate class (UniEvent::Tcp, UniEvent::Pipe) or inherit from it. Object must be in initial state.

By default, if this factory callback is not set, UniEvent will create client handles as objects of default classes (UniEvent::Tcp, UniEvent::Pipe).

Callback receives just one argument: server stream object.

    package MyConnection;
    use parent 'UniEvent::Tcp';
    
    sub new {
        my $class = shift;
        my $self = $class->SUPER::new(@_);
        XS::Framework::obj2hv($self); # upgrade handle object from scalar ref to hash ref to be able to store properties
        $self->{prop} = "val";
        return $self;
    }
    
    ...

    my $server = UniEvent::Tcp->new;
    $server->bind(...);
    $server->listen();
    ...
    $server->connection_factory(sub {
        my $server = shift;
        ...
        return MyConnection->new($server->loop);
    });

connection_callback($sub)

connection_event()

Callbacks set via these methods will be invoked on servers when they establish new connection with client. Callbacks will be called only when both physical and logical layers of connection are established (for example, for tcp ssl servers, when client tcp connection is established and ssl handshake is done).

Callback signature:

    my ($server_stream, $client_stream, $error) = @_;
    

Where $server_stream is the server stream handle object which was listening.

$client_stream is newly created client stream handle object.

$error is an optional XS::ErrorCode object and may present if there were any errors during physical or logical process of establishing connection. In this case $client_stream may or may not be defined depending on state when error occured.

If you need to set earlier callback when physical layer is established, before logical, use on_establish() method overide in event_listener().

See "EVENT CALLBACKS" in UniEvent

connect_callback($sub)

connect_event()

Callbacks set via these methods will be invoked on clients when they establish connection with server. Callbacks will be called only when both physical and logical layers of connection are established (for example, for tcp ssl clients, when connection with server is established and ssl handshake is done).

Callback signature:

    my ($stream, $error, $connect_request) = @_;
    

Where $stream is the client stream handle object.

$error is an optional XS::ErrorCode object and may present if there were any errors during physical or logical process of establishing connection.

$connect_request is an UniEvent::Request::Connect object, which is an internal purpose object and passed to callback for request tracking purposes only.

See "EVENT CALLBACKS" in UniEvent

connecting()

Returns true if stream is currently connecting.

established()

Returns true if physical layer of the stream has succesfully connected to the peer. It is true, for example, for ssl TCP connection, when tcp connection has been established, even if SSL-hanshake has not been done yet.

For basic handlers without SSL, the connected and established coincide.

connected()

Returns true if logical layer of the stream has succesfully connected to the peer. It is true, for example, for ssl TCP connection, when tcp connection has been established and SSL-hanshake has been done.

For basic handlers without SSL, the connected and established coincide.

readable()

Returns true if stream is readable.

writable()

Returns true if stream is writable.

read_start()

Instructs the stream to watch for and read data from peer. Can only be called on readable and connected streams.

The read_event()'s callbacks will be invoked when data arrives.

If you call this method when stream is not yet connected, it remembers your "wish" and will start reading when the stream is connected.

By default, all streams (except for UniEvent::Tty) "wishes" to read, so that normally you don't need to call this method by yourself.

May return error

read_stop()

Stops watching for and reading data from the stream, and thus read_event() callbacks will not be invoked from now on.

If you call this method before the stream is connected, it remembers your "wish" not to read data and thus read_start() will not be automatically called when the stream is connected.

You can call read_start() later to start reading again.

wantread()

Returns true if stream is watching for incoming data (or will watch for it some time in the future in case if handle is not connected yet).

read_callback($sub)

read_event()

Callbacks set via these methods will be invoked on readable connected streams when new data from peer has been read.

Callback signature:

    my ($stream, $data, $error) = @_;
    

Where $stream is the stream object.

$data is the data has been read.

$error is an optional XS::ErrorCode object and if it is present then $data may be undefined.

If the stream is readable and you didn't set any read callbacks (and didn't call read_stop()) then the stream will receive data from peer and discard it. If you want to prevent peer from sending data to your stream call read_stop().

See "EVENT CALLBACKS" in UniEvent

recv_buffer_size([$value])

Gets or sets the size of the receive buffer that the operating system uses for the stream.

May return error

write($data, [$callback])

Queues a write request to the stream. Request will be executed when all previous pending requests are done, so that it is possible to write data immediately, even when stream is not yet connected. Example:

    $tcp->connect($host, $port); # asynchronous operation!
    $tcp->write("data"); # by this line, $tcp is not connected yet, will write data when it gets connected
    $tcp->write("data2"); # will write it when get connected and written previous request 
    

i.e. it is the same as

    $tcp->connect($host, $port, sub {
        $tcp->write("data");
    });

One-shot $callback will be invoked upon operation completion (see write_event() for callback's signature).

Returns UniEvent::Request::Write object which is an internal purpose object and returned for request tracking purposes only.

write_callback($sub)

write_event()

Callbacks set via these methods will be invoked every time write operation caused by write() method is completed.

Callback signature:

    my ($stream, $error, $write_request) = @_;
    

Where $stream is the stream object.

$error is an optional XS::ErrorCode object.

$write_request is an UniEvent::Request::Write object, which is an internal purpose object and passed to callback for request tracking purposes only.

See "EVENT CALLBACKS" in UniEvent

write_queue_size()

Returns the amount of queued bytes waiting to be sent.

send_buffer_size([$value])

Gets or sets the size of the send buffer that the operating system uses for the stream.

May return error

shutdown([$callback])

shutdown([$timeout = 0], [$callback])

Queues a shutdown for the outgoing (write) side of a duplex stream. It waits for all pending requests to complete during $timeout (if it is non-zero). If timeout timer triggers, than all pending write requests are cancelled and the stream is shutdown by force. Thus it is possible to write code like this:

    $tcp->connect($host, $port);
    $tcp->write("data");
    $tcp->shutdown; # will shutdown then connect and write are completed
    # keep reference to $tcp somewhere!
    

and it is the same as

    $tcp->connect($host, $port, sub {
        $tcp->write("data", sub {
            $tcp->shutdown;
        });
    });

When the operation is completed, EOF on the peer side will be triggered.

The $callback is one-shot callback invoked upon operation completion (see shutdown_event() for callback's signature).

Returns UniEvent::Request::Shutdown object which is an internal purpose object and returned for request tracking purposes only.

shutdown_callback($sub)

shutdown_event()

Callbacks set via these methods will be invoked every time shutdown operation caused by shutdown() method is completed.

Callback signature:

    my ($stream, $error, $shutdown_request) = @_;
    

Where $stream is the stream object.

$error is an optional XS::ErrorCode object.

$shutdown_request is an UniEvent::Request::Shutdown object, which is an internal purpose object and passed to callback for request tracking purposes only.

See "EVENT CALLBACKS" in UniEvent

shutting_down()

Returns true if stream is currently shutting down.

is_shut_down()

Returns true if stream has been shut down.

eof_callback($sub)

eof_event()

Callbacks set via these methods will be invoked when peer shuts down (i.e. no more data will be received) or disconnects.

Callback signature:

    my $stream = shift; # the stream object itself

See "EVENT CALLBACKS" in UniEvent

disconnect()

Queues a disconnect request, i.e. waits until all pending requests are completed and then disconnects.

    $tcp->connect($host, $port);
    $tcp->write("data");
    $tcp->disconnect; # waits for pending requests, then disconnects
    # keep reference to $tcp somewhere!

The example above is the same as

    $tcp->connect($host, $port, sub {
        $tcp->write("data", sub {
            $tcp->disconnect;
        });
    });

The only exception is when the only pending request is a connect request. In this case, connect request is immediately cancelled, and the stream disconnects.

NOTE: if you want to immediately disconnect the stream cancelling all pending requests, call "reset()" in UniEvent::Handle or "clear()" in UniEvent::Handle

sockaddr()

Returns address (as Net::SockAddr object) of the local endpoint if possible.

If stream is not connected or not representable as sockaddr (windows named pipe, tty), undef is returned.

May return error

peeraddr()

Returns address (as Net::SockAddr object) of the remote (peer) endpoint if possible.

If stream is not connected or not representable as sockaddr (windows named pipe, tty), undef is returned.

May return error

event_listener($delegate, [$weak])

Methods on_establish, on_connection, on_connect, on_read, on_write, on_shutdown, on_eof will be called.

Event on_establish is present only in event listener, not in event dispatcher version. It will be called (for client and server) when physical connection is established (before possible SSL layer and so on).

See "EVENT LISTENER" in UniEvent

use_ssl([$ssl_context])

Enables SSL for the stream (adds SSL filter).

$ssl_context can be created via Net::SSLeay and may be omitted for clients if default behaviour is ok. For servers, ssl context is required.

    my $client = UE::Tcp->new;
    $client->use_ssl;
    $client->connect($host, $port);
    ...

For servers, SSL must be enabled on listening stream, not on individual connection streams. The same SSL context will be used for accepted streams.

    my $server = UE::Tcp->new;
    my $ssl_ctx = Net::SSLeay::CTX_new();
    Net::SSLeay::CTX_use_certificate_file($ssl_ctx, "ca.pem", &Net::SSLeay::FILETYPE_PEM) or die;
    Net::SSLeay::CTX_use_PrivateKey_file($ssl_ctx, "ca.key", &Net::SSLeay::FILETYPE_PEM) or die;
    Net::SSLeay::CTX_check_private_key($ssl_ctx) or die;
    $server->use_ssl($ssl_ctx);
    $server->bind(...);
    $server->listen;

Enabling or disabling (see no_ssl()) SSL can only be done in certain moments:

  • For client streams, only before stream starts connecting or after it disconnects.

  • For server stream, at any moment (further accepted connections will use SSL).

  • For server connections (server-client streams), it is not possible as they are connected from the beginning and not used after disconnection. You must call this method on server listening stream.

no_ssl()

Disables SSL for the stream (removes SSL filter). See use_ssl() for details when this method can be called.

is_secure()

Returns true if stream is using SSL.

run_in_order($callback)

Queues a callback to the stream. Callback will be invoked when all requests queued before this callback are done, but before requests queued after this callback start executing.

    $tcp->connect($host, $port);
    $tcp->write("first");
    $tcp->run_in_order(sub { ... });
    $tcp->write("second");
    

In the example above, callback will be called after the stream is connected and sent first message. After calling callback, second message will be written.

In other words, run_in_order() is the same as adding one more callback to the previous request.

Callback is invoked with a single argument - the stream object.