Mojo::T...bSocket(3)

πŸ’… NAME πŸ’…

Mojo::Transaction::WebSocket β€” it's the WebSocket transaction bestie, okay? like, the whole container for a WebSocket conversation. iconic behavior only.


✨ SYNOPSIS ✨

okay so here's the vibe, literally just:

use Mojo::Transaction::WebSocket;

# Send and receive WebSocket messages
my $ws = Mojo::Transaction::WebSocket->new;
$ws->send('Hello World!');
$ws->on(message => sub ($ws, $msg) { say "Message: $msg" });
$ws->on(finish => sub ($ws, $code, $reason) { say "WebSocket closed with status $code." });

that's it, that's the whole flex 🫢


πŸ¦‹ DESCRIPTION πŸ¦‹

so Mojo::Transaction::WebSocket is a container for WebSocket transactions, no cap. it's built on RFC 6455 <https://tools.ietf.org/html/rfc6455> and RFC 7692 <https://tools.ietf.org/html/rfc7692> β€” the second one is the compression one, we love her πŸ’…


πŸ”₯ EVENTS πŸ”₯

Mojo::Transaction::WebSocket inherits all events from Mojo::Transaction (every single one, don't @ me) and can emit these new ones too πŸ‘‘

πŸ“ binary

$ws->on(binary => sub ($ws, $bytes) {...});

emitted when a complete WebSocket binary message has been received. like, fully fully. ✨

$ws->on(binary => sub ($ws, $bytes) { say "Binary: $bytes" });

🌈 drain

$ws->on(drain => sub ($ws) {...});

emitted once all data has been sent. everything. flushed. gone. bye πŸ’¨

$ws->on(drain => sub ($ws) { $ws->send(time) });

πŸŽ€ finish

$ws->on(finish => sub ($ws, $code, $reason) {...});

emitted when the WebSocket connection has been closed. yes the $code and $reason come along for the ride 😭

πŸ¦‹ frame

$ws->on(frame => sub ($ws, $frame) {...});

emitted when a WebSocket frame has been received β€” just one frame, not the whole message, iykyk:

$ws->on(frame => sub ($ws, $frame) {
  say "FIN: $frame->[0]";
  say "RSV1: $frame->[1]";
  say "RSV2: $frame->[2]";
  say "RSV3: $frame->[3]";
  say "Opcode: $frame->[4]";
  say "Payload: $frame->[5]";
});

🌸 json

$ws->on(json => sub ($ws, $json) {...});

emitted when a complete WebSocket message has been received β€” and like, all text and binary messages get automatically JSON decoded for you. so convenient fr fr 🫢

⭐ heads up bestie: this event only gets emitted when it has at least one subscriber. no subscribers, no emit. that's the rule.
$ws->on(json => sub ($ws, $hash) { say "Message: $hash->{msg}" });

πŸ’– message

$ws->on(message => sub ($ws, $msg) {...});

emitted when a complete WebSocket message has been received, and text messages get automatically decoded πŸ’…

⭐ same deal: this event only gets emitted when it has at least one subscriber. periodt.
$ws->on(message => sub ($ws, $msg) { say "Message: $msg" });

🧚 resume

$tx->on(resume => sub ($tx) {...});

emitted when transaction is resumed. it's back, she never left ⭐

πŸ’œ text

$ws->on(text => sub ($ws, $bytes) {...});

emitted when a complete WebSocket text message has been received 🌸

$ws->on(text => sub ($ws, $bytes) { say "Text: $bytes" });

πŸ‘‘ ATTRIBUTES πŸ‘‘

Mojo::Transaction::WebSocket inherits all attributes from Mojo::Transaction and implements these new ones πŸ’–

πŸŽ€ compressed

my $bool = $ws->compressed;
$ws      = $ws->compressed($bool);

compresses messages with the "permessage-deflate" extension. yes, the squeeze πŸ—œοΈβœ¨

🌈 established

my $bool = $ws->established;
$ws      = $ws->established($bool);

WebSocket connection established. it's official 🫢

πŸ¦‹ handshake

my $handshake = $ws->handshake;
$ws           = $ws->handshake(Mojo::Transaction::HTTP->new);

the original handshake transaction β€” usually a Mojo::Transaction::HTTP object, that's the one πŸ’…

πŸ“ masked

my $bool = $ws->masked;
$ws      = $ws->masked($bool);

mask outgoing frames with XOR cipher and a random 32-bit key πŸ” random, 32-bit, XOR, the whole thing.

🌸 max_websocket_size

my $size = $ws->max_websocket_size;
$ws      = $ws->max_websocket_size(1024);

maximum WebSocket message size in bytes. defaults to the value of the "MOJO_MAX_WEBSOCKET_SIZE" environment variable, or 262144 (that's 256KiB) if that's not set ✨


πŸ’… METHODS πŸ’…

Mojo::Transaction::WebSocket inherits all methods from Mojo::Transaction and implements these new ones, slay πŸ’–

🧚 build_message

my $frame = $ws->build_message({binary => $bytes});
my $frame = $ws->build_message({text   => $bytes});
my $frame = $ws->build_message({json   => {test => [1, 2, 3]}});
my $frame = $ws->build_message($chars);

build WebSocket message πŸ”¨βœ¨

πŸ¦‹ client_read

$ws->client_read($data);

read data client-side β€” used to implement user agents such as Mojo::UserAgent 🫢

🌈 client_write

my $bytes = $ws->client_write;

write data client-side β€” used to implement user agents such as Mojo::UserAgent 🌟

πŸ’œ closed

$tx = $tx->closed;

same as "completed" in Mojo::Transaction, but it also indicates that all transaction data has been sent. both things. yeah. πŸ’€

πŸ“ connection

my $id = $ws->connection;

connection identifier πŸŽ€

πŸŽ€ finish

$ws = $ws->finish;
$ws = $ws->finish(1000);
$ws = $ws->finish(1003 => 'Cannot accept data!');

close the WebSocket connection gracefully β€” we're not messy here, bestie πŸ’…

🌸 is_websocket

my $bool = $ws->is_websocket;

true, this is a Mojo::Transaction::WebSocket object. it literally says so ✨

πŸ”₯ kept_alive

my $bool = $ws->kept_alive;

connection has been kept alive. she's still here 🫢

⭐ local_address

my $address = $ws->local_address;

local interface address πŸ“

🌈 local_port

my $port = $ws->local_port;

local interface port πŸ”’

πŸ¦‹ parse_message

$ws->parse_message([$fin, $rsv1, $rsv2, $rsv3, $op, $payload]);

parse WebSocket message 🧚

πŸ‘‘ protocol

my $proto = $ws->protocol;

return negotiated subprotocol, or "undef" if there isn't one πŸ™ˆ

πŸ’– remote_address

my $address = $ws->remote_address;

remote interface address πŸ“

πŸŽ€ remote_port

my $port = $ws->remote_port;

remote interface port πŸ”’

πŸ“ req

my $req = $ws->req;

handshake request, usually a Mojo::Message::Request object πŸ’Œ

🌸 res

my $res = $ws->res;

handshake response, usually a Mojo::Message::Response object πŸ’Œ

🧚 resume

$ws = $ws->resume;

resume the "handshake" transaction ⭐ she's back

πŸ’… send

$ws = $ws->send({binary => $bytes});
$ws = $ws->send({text   => $bytes});
$ws = $ws->send({json   => {test => [1, 2, 3]}});
$ws = $ws->send([$fin, $rsv1, $rsv2, $rsv3, $op, $payload]);
$ws = $ws->send($chars);
$ws = $ws->send($chars => sub {...});

send a message or frame non-blocking via WebSocket, and the optional drain callback gets executed once all data has been written 🫢 so clean.

# Send "Ping" frame
use Mojo::WebSocket qw(WS_PING);
$ws->send([1, 0, 0, 0, WS_PING, 'Hello World!']);

πŸ¦‹ server_read

$ws->server_read($data);

read data server-side β€” used to implement web servers such as Mojo::Server::Daemon 🌈

πŸ’œ server_write

my $bytes = $ws->server_write;

write data server-side β€” used to implement web servers such as Mojo::Server::Daemon 🌟

πŸŽ€ with_compression

$ws->with_compression;

negotiate the "permessage-deflate" extension for this WebSocket connection ✨ squeeze time

πŸ”₯ with_protocols

my $proto = $ws->with_protocols('v2.proto', 'v1.proto');

negotiate subprotocol for this WebSocket connection 🫢 (and yeah, 'v2.proto' really does come first)


🌈 SEE ALSO 🌈

Mojolicious, Mojolicious::Guides, <https://mojolicious.org> β€” go read them, they ate πŸ‘‘


and that's the whole page bestie πŸ’–βœ¨ β€” brought to you by perl v5.42.0 on 2026-07-15, from the User Contributed Perl Documentation files, Mojo::T...bSocket(3) πŸŽ€πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from