NAME
Net::Async::Kubernetes::PortForwardSession - Duplex websocket session for pod port-forward, exec and attach
VERSION
version 0.008
SYNOPSIS
my $session = $kube->exec('Pod', 'my-pod',
namespace => 'default',
command => ['sh'],
tty => 1,
on_frame => sub {
my ($channel, $payload) = @_;
print $payload if $channel == 1; # stdout
},
)->get;
$session->write_stdin("id\n");
$session->resize(width => 120, height => 40);
$session->close(code => 1000);
DESCRIPTION
A duplex session handle for the Kubernetes exec/attach/port-forward websocket sub-protocol (v4.channel.k8s.io by default). Every frame on the wire carries a channel number as its first byte, identifying which logical stream - stdin, stdout, stderr, error/status, or TTY resize - the rest of the frame belongs to. write_channel is the primitive that builds such a frame; write_stdin and resize are convenience wrappers over channels 0 and 4 respectively.
Callers do not normally construct this class themselves: it is what "port_forward" in Net::Async::Kubernetes, "exec" in Net::Async::Kubernetes, and "attach" in Net::Async::Kubernetes resolve their returned Future with, and what they pass to an on_open callback if one was given. Incoming frames are not read through this object; they arrive via the on_frame callback passed to those methods, already decoded into ($channel, $payload) pairs.
new
my $session = Net::Async::Kubernetes::PortForwardSession->new(
ws_client => $ws_client,
);
Wraps an already-connected websocket client (normally a Net::Async::WebSocket::Client) as a session. ws_client is required.
Callers do not normally build a session this way: the Future returned by "port_forward" in Net::Async::Kubernetes, "exec" in Net::Async::Kubernetes, and "attach" in Net::Async::Kubernetes resolves to one, already bound to the open connection, and it is what those methods pass to an on_open callback.
write_channel
$session->write_channel(0, "id\n");
Send $payload as a single binary websocket frame on the given Kubernetes stream $channel, with the channel number prepended as the frame's first byte (chr($channel) . $payload). $channel is required and must be an integer between 0 and 255; $payload defaults to the empty string.
write_channel itself does not know what any channel number means, it only frames whatever it is given, but the Kubernetes exec/attach/port-forward sub-protocol fixes their meaning: 0 is stdin, 1 is stdout, 2 is stderr, 3 carries an error/status JSON document, and 4 carries TTY resize events (see "resize"). on_frame, passed to "exec" in Net::Async::Kubernetes and friends, decodes incoming frames the same way in reverse.
Returns the Future from the underlying ws_client's send_binary_frame - an IO::Async::Stream write-future that completes with no value once the frame has been flushed to the connection.
Aliased as write.
write_stdin
$session->write_stdin("id\n");
Shortcut for $session->write_channel(0, $payload) - writes to channel 0, the stdin stream of an exec or attach session's remote process.
Returns the Future from the underlying write_channel call.
Aliased as stdin.
resize
$session->resize(width => 120, height => 40);
$session->resize(cols => 120, rows => 40); # cols/rows are accepted too
Send a TTY resize event on channel 4, as a {"Width":$width,"Height":$height} JSON payload. width and height (or their cols/rows aliases) are required and must be positive integers. Only meaningful for a session opened with tty => 1.
Returns the Future from the underlying write_channel call.
close
$session->close(code => 1000, payload => 'bye');
$session->close; # close frame with no code
Send a websocket close frame, ending the session. code, if given, must be a websocket close code between 1000 and 4999; it is packed as a 16-bit big-endian prefix (pack('n', $code)) ahead of payload, which defaults to the empty string. Once the close frame is sent, the underlying transport is also asked to close the connection once its write buffer drains (close_when_empty), if the transport supports that method.
Returns the Future from the underlying ws_client's send_close_frame - an IO::Async::Stream write-future that completes with no value once the close frame has been flushed to the connection.
SEE ALSO
Net::Async::Kubernetes, Net::Async::WebSocket::Client, IO::Async::Stream
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-net-async-kubernetes/issues.
IRC
Join #kubernetes on irc.perl.org or message Getty directly.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHOR
Torsten Raudssus <torsten@raudssus.de>
COPYRIGHT AND LICENSE
This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.