NAME
Linux::Event::IO::Sock::Stream - Asynchronous connected sockets
SYNOPSIS
use v5.36;
use Linux::Event::Loop;
use Linux::Event::IO::Sock::Stream;
my $loop = Linux::Event::Loop->new;
my $stream = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
host => 'example.com',
port => 80,
on_ready => sub ($self) {
$self->write("GET / HTTP/1.0\r\n\r\n");
},
on_data => sub ($self, $bytes) {
print $bytes;
},
on_error => sub ($self, $error) {
warn "$error\n";
},
on_close => sub ($self) {
$loop->stop;
},
);
$loop->run;
DESCRIPTION
Linux::Event::IO::Sock::Stream represents one connected stream socket.
It is used for:
TCP connections over IPv4
TCP connections over IPv6
Unix-domain stream sockets
outbound client connections
connections accepted by Linux::Event::IO::Sock::Listener
already-connected sockets adopted from other code
A Stream handles the connection asynchronously.
Your application supplies callbacks such as on_ready, on_data, on_error, and on_close, and Linux::Event calls them when something happens.
The same Stream class also supports framing, TLS, buffering, backpressure, timeouts, socket configuration, and protocol transitions when those features are needed.
CONNECTING TO A SERVER
Use connect to create an outbound connection:
my $stream = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
host => 'example.com',
port => 1234,
on_ready => sub ($self) {
say "Connected";
},
on_data => sub ($self, $bytes) {
say "Received: $bytes";
},
);
Hostname lookup and connection establishment happen asynchronously.
The Stream object exists immediately and keeps the same identity through DNS resolution, connection establishment, optional TLS negotiation, normal I/O, and final close.
loop
loop => $loop
Attach the Stream to a Loop immediately.
The loop option is optional.
Without it, connect returns a detached Stream:
my $stream = Linux::Event::IO::Sock::Stream->connect(
host => 'example.com',
port => 1234,
...
);
$loop->add($stream);
host and port
For a TCP connection:
host => 'example.com',
port => 1234,
host may require asynchronous DNS resolution.
Unix-domain sockets
Use unix instead of host and port:
my $stream = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
unix => '/run/my-service.sock',
...
);
timeout
timeout => 10
Set the connection-establishment timeout in seconds.
The default is 10 seconds.
This timeout covers connection establishment rather than the later established-connection timeout policy.
data
data => $value
Store arbitrary application data with the Stream.
This is useful when a connection needs to carry application-specific state.
Local address options
Outbound TCP connections may optionally specify:
local_host => '192.0.2.10',
local_port => 0,
bind_device may also be used when the connection must be bound to a particular Linux network device.
These options are normally unnecessary.
WHEN THE CONNECTION IS READY
on_ready
on_ready => sub ($self) {
...
}
on_ready is called once when the connection is ready for application use.
For a normal TCP connection, this is after connection establishment.
For a TLS connection, this is after the TLS handshake and verification have completed.
This means application protocols can normally begin their work in on_ready without needing to know whether the underlying connection is plain or TLS.
For example:
on_ready => sub ($self) {
$self->write("HELLO\r\n");
}
RECEIVING DATA
on_data
For an unframed Stream, incoming bytes are delivered to on_data:
on_data => sub ($self, $bytes) {
print $bytes;
}
$bytes contains the next available part of the ordered byte stream.
TCP does not preserve application message boundaries.
For example, two writes by the remote peer may arrive in one on_data callback, or one remote write may arrive across several callbacks.
If your protocol has messages, use Linux::Event::Framer rather than assuming that one on_data call equals one message.
SENDING DATA
write($bytes)
$stream->write("hello");
write sends raw bytes on the connection.
Linux::Event first attempts to write immediately.
If the socket cannot accept all of the data, the remaining bytes are queued and written later when the socket becomes writable again.
Data is kept in order.
You do not need to manually watch the socket for writable readiness.
Writing before on_ready
Data may be queued before the connection becomes ready:
my $stream = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
host => 'example.com',
port => 1234,
...
);
$stream->write("hello");
The bytes remain queued and are sent when the transport becomes usable.
For many protocols it is still clearer to begin application communication from on_ready.
send($payload)
$stream->send($payload);
send is used by framed Stream subclasses.
It applies the subclass's Linux::Event::Framer to the payload before placing the resulting bytes on the wire.
For an unframed protocol, use write.
CLOSING A CONNECTION
close
$stream->close;
Close the connection immediately.
close is terminal.
Pending output does not need to finish first.
end
$stream->end;
Finish queued output and then perform the writable half-close appropriate for the transport.
Use end when a protocol wants to finish sending data cleanly rather than aborting the connection immediately.
on_close
on_close => sub ($self) {
...
}
Called when the Stream reaches its terminal closed state.
on_eof
on_eof => sub ($self) {
...
}
Called when the peer closes its sending side and the Stream reaches input EOF.
EOF and immediate connection destruction are not the same event, so protocols that care about half-close behavior may handle on_eof separately.
ERRORS
on_error
on_error => sub ($self, $error) {
warn "Connection error: $error\n";
}
Called when the Stream encounters an asynchronous connection or I/O error.
$error is a Linux::Event::Error object.
The Stream's last_error method can be used to inspect the most recent stored error.
PAUSING INPUT
pause_read
$stream->pause_read;
Temporarily stop delivering application input.
resume_read
$stream->resume_read;
Resume application input.
This is useful when the application needs to slow consumption without closing the connection.
Read timeout handling is suspended while input is deliberately paused.
BACKPRESSURE
A Stream has an output queue for bytes that the kernel cannot accept immediately.
Linux::Event provides high and low watermarks so applications can react when that queue becomes large.
write and send still accept the supplied data when the high watermark is reached, but begin returning false to tell the application that it should slow down.
When queued output later falls to the low watermark, on_drain is called.
on_drain
on_drain => sub ($self) {
say "Output has drained; producing more data is safe";
}
A typical producer can therefore stop generating more data when write returns false and resume from on_drain.
CALLBACKS
Stream behavior may be supplied with constructor callbacks:
my $stream = Linux::Event::IO::Sock::Stream->connect(
loop => $loop,
host => 'example.com',
port => 1234,
on_data => sub ($self, $bytes) {
...
},
);
or by subclass methods:
package MyConnection;
use parent 'Linux::Event::IO::Sock::Stream';
sub on_data ($self, $bytes) {
...
}
A constructor callback overrides a same-named subclass method for that particular Stream.
This lets a reusable protocol class define normal behavior while an individual connection supplies special application state when necessary.
Available callbacks
The normal Stream callbacks are:
on_ready($stream)-
The connection is ready for application use.
on_data($stream, $bytes)-
Raw unframed input arrived.
on_message($stream, $message)-
One complete framed message arrived.
on_messages($stream, $messages)-
A batch of framed messages arrived when message batching is enabled.
on_drain($stream)-
Queued output fell back to the low watermark after backpressure.
on_eof($stream)-
The peer reached input EOF.
on_error($stream, $error)-
An asynchronous error occurred.
on_close($stream)-
The Stream closed.
on_transport_ready($stream)-
The lower-level transport became ready.
This is mainly useful to transport implementations and specialized protocol code. Normal applications should usually use
on_ready.
ADOPTING AN EXISTING SOCKET
Use new when you already have a connected SOCK_STREAM socket:
my $stream = Linux::Event::IO::Sock::Stream->new(
loop => $loop,
fh => $socket,
on_data => sub ($self, $bytes) {
...
},
);
Linux::Event validates the handle and configures it for nonblocking, close-on-exec operation.
The connection is already established, so an adopted plain socket does not later emit on_ready.
If the Stream class declares TLS, an adopted socket must also specify whether it is acting as the TLS client or server because Linux::Event cannot infer that from an already-connected handle.
ACCEPTED CONNECTIONS
Linux::Event::IO::Sock::Listener creates Stream objects for accepted connections.
For example:
my $listener = Linux::Event::IO::Sock::Listener->new(
loop => $loop,
host => '0.0.0.0',
port => 5000,
stream => {
on_data => sub ($self, $bytes) {
$self->write($bytes);
},
},
);
The Listener may also specify a Stream subclass, framing, TLS, tuning, and callbacks for all accepted connections.
See Linux::Event::IO::Sock::Listener.
FRAMED PROTOCOLS
Raw TCP carries bytes, not messages.
Linux::Event can perform message framing before your Perl callback runs.
For example, a line-oriented protocol can define:
package LineConnection;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'Delimiter', "\n";
sub on_message ($self, $message) {
say "Received complete line: $message";
}
Incoming bytes are accumulated until the framer finds a complete message.
Your application then receives on_message instead of having to maintain its own partial-input buffer.
To send a framed message:
$stream->send("hello");
The framer converts the payload to its wire representation.
See Linux::Event::Framer for the available framing methods.
SUBCLASSING
Subclassing is optional.
For a simple connection, constructor callbacks are often all that is needed:
my $stream = Linux::Event::IO::Sock::Stream->connect(
...
on_data => sub ($self, $bytes) {
...
},
);
Subclassing is useful when many connections share a protocol or configuration.
A subclass can define:
callback methods
framing
TLS defaults
socket options
Stream tuning
its own ordinary Perl instance state
For example:
package ChatConnection;
use parent 'Linux::Event::IO::Sock::Stream';
use Linux::Event::Framer 'Delimiter', "\n";
sub on_message ($self, $message) {
...
}
Subclass instance data
A Stream subclass is an ordinary Perl class.
It may store its own fields:
package StatefulConnection;
use parent 'Linux::Event::IO::Sock::Stream';
sub new ($class, %option) {
my $self = $class->SUPER::new(%option);
$self->{message_count} = 0;
return $self;
}
sub on_data ($self, $bytes) {
$self->{message_count}++;
...
}
Linux::Event leaves unrelated subclass-owned fields alone.
A subclass constructor should remove or handle its own constructor arguments and pass only Linux::Event options to SUPER::new.
TLS
TLS is a capability of a Stream connection, not a separate public Stream type.
This means application code can generally treat plain and encrypted connections the same way.
For accepted connections, TLS is commonly selected by the Listener:
my $listener = Linux::Event::IO::Sock::Listener->new(
loop => $loop,
host => '0.0.0.0',
port => 9443,
stream => {
class => 'ServerConnection',
tls => {
cert_file => $cert_file,
key_file => $key_file,
alpn => ['my-protocol/1'],
},
},
);
The same Stream subclass can be used by another Listener without TLS.
Framing and application callbacks always see plaintext.
on_ready occurs after TLS negotiation is complete.
See Linux::Event::TLS for TLS configuration.
SOCKET OPTIONS
A Stream subclass may define socket_options when every connection of that class should use the same socket settings.
For example:
package LowLatencyConnection;
use parent 'Linux::Event::IO::Sock::Stream';
sub socket_options ($class) {
return (
tcp_nodelay => 1,
keepalive => 1,
);
}
Constructor options may override class socket policy for one connection.
Supported socket options are described below.
tcp_nodelay
Boolean 0 or 1 controlling TCP_NODELAY.
TCP only.
keepalive
Boolean 0 or 1 controlling SO_KEEPALIVE.
TCP only.
keepalive_idle
Positive integer number of seconds before the first TCP keepalive probe.
keepalive_interval
Positive integer number of seconds between TCP keepalive probes.
keepalive_count
Positive integer number of failed TCP keepalive probes allowed.
tcp_user_timeout
Non-negative number of seconds for Linux TCP_USER_TIMEOUT.
Fractional seconds are accepted and rounded up to milliseconds.
TCP only.
send_buffer
Positive integer requested SO_SNDBUF size.
receive_buffer
Positive integer requested SO_RCVBUF size.
Other socket configuration
bind_device is a constructor option rather than a socket_options key.
Advanced subclasses may use configure_socket for Linux socket options not covered by the normal policy.
See docs/SOCKET-CONFIGURATION.md for the detailed application order and failure behavior.
STREAM TUNING
Most applications should use the defaults.
Linux::Event's Stream defaults are intended to provide good performance and fairness without application tuning.
When measurements show that a particular protocol needs different behavior, a subclass may define stream_tuning:
package TunedConnection;
use parent 'Linux::Event::IO::Sock::Stream';
sub stream_tuning ($class) {
return (
read_size => 131_072,
read_budget_bytes => 524_288,
high_watermark => 2_097_152,
low_watermark => 524_288,
idle_timeout => 60,
);
}
The method may return key/value pairs or one hash reference.
read_size
Default: 65,536 bytes.
Maximum number of bytes requested by one native read.
It must be a positive integer.
read_budget_bytes
Default: 65,536 bytes.
Maximum amount of data one readiness turn may read before yielding to other Loop resources.
This limit exists for fairness.
Without a limit, a socket that is continuously receiving data could keep one read callback busy while timers or other sockets are already ready.
A value of zero explicitly requests unlimited draining until the socket would block.
read_batch_bytes
Default: 0.
For an unframed Stream, successful reads may be combined before on_data is called.
A value of zero preserves normal read callback boundaries.
This option cannot be used with framing.
message_batch_size
Default: 0.
For framed Streams, deliver up to this many complete messages together through on_messages.
A value of zero uses normal on_message delivery.
A positive value requires framing and an on_messages callback.
max_buffer
Default: 8,388,608 bytes.
Hard maximum for retained input, incomplete framing data, and data retained for one message batch.
high_watermark
Default: 1,048,576 bytes.
When pending output reaches this level, write and send begin returning false to signal backpressure.
The supplied data is still accepted unless a hard pending-output limit prevents it.
low_watermark
Default: 262,144 bytes.
After backpressure has occurred, on_drain fires when queued output falls to or below this level.
The low watermark cannot be greater than the high watermark.
max_pending_bytes
Default: 0.
Hard limit on pending output bytes.
Zero means there is no hard limit.
idle_timeout
Default: 0.
Maximum number of seconds without successful established input or output progress.
Zero disables the timeout.
read_timeout
Default: 0.
Maximum number of seconds without inbound progress while reading is active.
A deliberate pause_read suspends this timeout.
Zero disables it.
write_timeout
Default: 0.
Maximum number of seconds without output progress while data remains queued.
Zero disables it.
CHANGING TUNING AT RUNTIME
tune
A live Stream can change its mutable tuning policy:
$stream->tune(
high_watermark => 2_097_152,
low_watermark => 524_288,
idle_timeout => 30,
);
tune accepts these settings:
read_size
read_budget_bytes
read_batch_bytes
message_batch_size
high_watermark
low_watermark
max_pending_bytes
max_buffer
idle_timeout
read_timeout
write_timeout
tune returns the Stream.
It cannot change the Stream's framer, callback structure, native protocol consumer, or transport type.
Changing watermarks immediately recalculates backpressure state.
Reducing a hard limit does not discard data that is already buffered or queued, but future growth must obey the new limit.
tune cannot be used after the Stream has closed.
DEADLINES
Established Streams may also use an explicit deadline in addition to the idle, read, and write timeout policy.
Connection establishment, TLS handshake, TLS shutdown, and established I/O use their own lifecycle deadlines rather than one ambiguous timeout covering every phase.
ADDRESSES
local
my $address = $stream->local;
Return the local Linux::Event::Address when available.
peer
my $address = $stream->peer;
Return the peer Linux::Event::Address when available.
The Address object represents IPv4, IPv6, or Unix-domain addresses as appropriate.
CONNECTION INFORMATION
fd
Return the underlying integer file descriptor when available.
fh
Return the Stream's Perl socket handle when available.
state
Return the current connection state.
pending_bytes
Return the number of output bytes currently waiting to be written.
last_error
Return the Stream's most recently stored error, when one exists.
DETACHING A SOCKET
detach
detach transfers an established plain socket out of Linux::Event.
Detachment is allowed only when it can be done without losing queued output or transport state.
In particular, a plain connection must have no pending output.
Encrypted transports cannot be safely detached because the TLS state is part of the connection.
PROTOCOL TRANSITIONS
transition_to
transition_to allows a live connection to change protocol handling without replacing the socket itself.
The Stream keeps its live transport, queued output, and unread input while the new protocol policy takes over according to the transition rules.
This is useful for protocols that intentionally change modes during one connection, such as an HTTP connection upgrading to WebSocket.
Linux::Event also supports native protocol consumers that operate directly on the Stream's native input buffer.
A native consumer may hand the connection to another native consumer, or retire into an ordinary Perl input callback, while preserving unread bytes.
Adding a native consumer after ordinary Perl input has already been active is not supported.
These are advanced protocol-engine facilities.
See docs/FRAMING.md for the complete transition contract.
PERFORMANCE MODEL
Linux::Event resolves Stream callbacks and reusable class policy when the connection is constructed.
Normal input delivery does not repeatedly search the object's Perl hash for a callback or decide between a method and constructor callback for every event.
Framing, buffering, output queuing, and readiness handling are implemented by the native ordered-byte engine.
These details normally require no application action; they explain why subclass policy and constructor callbacks can be combined without forcing the application into one style.
SEE ALSO
Linux::Event, Linux::Event::Loop, Linux::Event::IO::Sock::Listener, Linux::Event::IO::Sock::Dgram, Linux::Event::Framer, Linux::Event::TLS, Linux::Event::Address, Linux::Event::Error, docs/SOCKET-CONNECTIONS.md, docs/ORDERED-BYTE-IO-DESIGN.md, docs/FIRST-CLASS-STREAM-CALLBACKS.md, docs/FRAMING.md.