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
- opensuse-leap 16.0: perl-Mojolicious 9.480.0-bp160.2.1 Β· Artistic-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms