The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Mojo::Transaction::WebSocket - WebSocket transaction

SYNOPSIS

use Mojo::Transaction::WebSocket;

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

DESCRIPTION

Mojo::Transaction::WebSocket is a container for WebSocket transactions as described in RFC 6455. Note that 64bit frames require a Perl with 64bit integer support, or they are limited to 32bit.

EVENTS

Mojo::Transaction::WebSocket inherits all events from Mojo::Transaction and can emit the following new ones.

drain

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

Emitted once all data has been sent.

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

frame

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

Emitted when a WebSocket frame has been received.

$ws->unsubscribe('frame');
$ws->on(frame => sub {
  my ($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]";
});

message

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

Emitted when a complete WebSocket message has been received.

$ws->on(message => sub {
  my ($ws, $msg) = @_;
  say "Message: $msg";
});

ATTRIBUTES

Mojo::Transaction::WebSocket inherits all attributes from Mojo::Transaction and implements the following new ones.

handshake

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

The original handshake transaction, defaults to a Mojo::Transaction::HTTP object.

masked

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

Mask outgoing frames with XOR cipher and a random 32bit key.

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.

METHODS

Mojo::Transaction::WebSocket inherits all methods from Mojo::Transaction and implements the following new ones.

new

my $multi = Mojo::Content::MultiPart->new;

Construct a new Mojo::Transaction::WebSocket object and subscribe to frame event with default message parser, which also handles PING and CLOSE frames automatically.

build_frame

my $bytes = $ws->build_frame($fin, $rsv1, $rsv2, $rsv3, $op, $payload);

Build WebSocket frame.

# Continuation frame with FIN bit and payload
say $ws->build_frame(1, 0, 0, 0, 0, 'World!');

# Text frame with payload
say $ws->build_frame(0, 0, 0, 0, 1, 'Hello');

# Binary frame with FIN bit and payload
say $ws->build_frame(1, 0, 0, 0, 2, 'Hello World!');

# Close frame with FIN bit and without payload
say $ws->build_frame(1, 0, 0, 0, 8, '');

# Ping frame with FIN bit and payload
say $ws->build_frame(1, 0, 0, 0, 9, 'Test 123');

# Pong frame with FIN bit and payload
say $ws->build_frame(1, 0, 0, 0, 10, 'Test 123');

client_challenge

my $success = $ws->client_challenge;

Check WebSocket handshake challenge client-side.

client_handshake

$ws->client_handshake;

Perform WebSocket handshake client-side.

client_read

$ws->client_read($data);

Read and process data client-side.

client_write

my $chunk = $ws->client_write;

Write data client-side.

connection

my $connection = $ws->connection;

Connection identifier or socket.

finish

$ws = $ws->finish;

Finish the WebSocket connection gracefully.

is_websocket

my $true = $ws->is_websocket;

True.

kept_alive

my $kept_alive = $ws->kept_alive;

Connection has been kept alive.

local_address

my $address = $ws->local_address;

Local interface address.

local_port

my $port = $ws->local_port;

Local interface port.

parse_frame

my $frame = $ws->parse_frame(\$bytes);

Parse WebSocket frame.

# Parse single frame and remove it from buffer
my $frame = $ws->parse_frame(\$buffer);
say "FIN: $frame->[0]";
say "RSV1: $frame->[1]";
say "RSV2: $frame->[2]";
say "RSV3: $frame->[3]";
say "Opcode: $frame->[4]";
say "Payload: $frame->[5]";

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 handshake transaction.

send

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

Send message or frame non-blocking via WebSocket, the optional drain callback will be invoked once all data has been written.

# Send "Ping" frame
$ws->send([1, 0, 0, 0, 9, 'Hello World!']);

server_handshake

$ws->server_handshake;

Perform WebSocket handshake server-side.

server_read

$ws->server_read($data);

Read and process data server-side.

server_write

my $chunk = $ws->server_write;

Write data server-side.

DEBUGGING

You can set the MOJO_WEBSOCKET_DEBUG environment variable to get some advanced diagnostics information printed to STDERR.

MOJO_WEBSOCKET_DEBUG=1

SEE ALSO

Mojolicious, Mojolicious::Guides, http://mojolicio.us.