NAME
PAGI::Endpoint::WebSocket - Class-based WebSocket endpoint handler
SYNOPSIS
package MyApp::Chat;
use parent 'PAGI::Endpoint::WebSocket';
use Future::AsyncAwait;
sub encoding { 'json' } # or 'text', 'bytes'
async sub on_connect {
my ($self, $ctx) = @_;
await $ctx->websocket->accept;
await $ctx->websocket->send_json({ type => 'welcome' });
}
async sub on_receive {
my ($self, $ctx, $data) = @_;
await $ctx->websocket->send_json({ type => 'echo', message => $data });
}
sub on_disconnect {
my ($self, $ctx, $code) = @_;
cleanup_user($ctx->stash->get('user_id'));
}
# Use with PAGI server
my $app = MyApp::Chat->to_app;
DESCRIPTION
PAGI::Endpoint::WebSocket provides a Starlette-inspired class-based approach to handling WebSocket connections with lifecycle hooks.
LIFECYCLE METHODS
on_connect
async sub on_connect {
my ($self, $ctx) = @_;
await $ctx->websocket->accept;
}
Called when a client connects. You should call $ctx->websocket->accept to accept the connection. If not defined, connection is auto-accepted.
on_receive
async sub on_receive {
my ($self, $ctx, $data) = @_;
await $ctx->websocket->send_text("Got: $data");
}
Called for each message received. The $data format depends on the encoding() setting.
on_disconnect
sub on_disconnect {
my ($self, $ctx, $code, $reason) = @_;
# Cleanup
}
Called when connection closes. This is synchronous (not async).
CLASS METHODS
encoding
sub encoding { 'json' } # 'text', 'bytes', or 'json'
Controls how incoming messages are decoded before being passed to on_receive. This does not affect outgoing messages - you always explicitly choose the send method (send_json, send_text, send_bytes).
text- Messages passed as strings (default)bytes- Messages passed as raw bytesjson- Messages automatically decoded from JSON to Perl data structures
Example - JSON encoding:
package MyEndpoint;
use parent 'PAGI::Endpoint::WebSocket';
sub encoding { 'json' } # Incoming messages auto-decoded from JSON
async sub on_receive {
my ($self, $ctx, $data) = @_;
# $data is already a Perl hashref/arrayref (decoded from JSON)
my $name = $data->{name};
# For sending, you still explicitly choose the method:
await $ctx->websocket->send_json({ greeting => "Hello, $name" });
await $ctx->websocket->send_text("Raw text message");
}
Example - Text encoding:
sub encoding { 'text' } # Incoming messages as raw strings
async sub on_receive {
my ($self, $ctx, $text) = @_;
# $text is a plain string, decode JSON yourself if needed
my $data = JSON::MaybeXS::decode_json($text);
await $ctx->websocket->send_text("Echo: $text");
}
This follows the same pattern as Starlette's WebSocketEndpoint.
context_class
sub context_class { 'PAGI::Context' }
Override to use a custom context class.
to_app
my $app = MyEndpoint->to_app;
Returns a PAGI-compatible async coderef.
SEE ALSO
PAGI::Context, PAGI::WebSocket, PAGI::Endpoint::HTTP, PAGI::Endpoint::SSE