NAME
Discord::Client::Gateway - Discord Gateway connections and events
SYNOPSIS
use Discord::Client::Gateway;
# Configure the connection.
my $gateway = Discord::Client::Gateway->new(
token => $ENV{DISCORD_BOT_TOKEN}, loop => $loop, intents => ['GUILDS'],
);
# Return asynchronous work from the event handler.
$gateway->on(MESSAGE_CREATE => sub {
my ($data, $gateway, $packet) = @_;
return handle_message($data);
});
# Start on the application's loop.
my $ready = $gateway->connect;
DESCRIPTION
Receives Discord v10 JSON events and manages the WebSocket connection, heartbeats, Resume and reconnects. Use it independently or through Discord::Client. The caller drives the loop. Standalone Gateway intents default to zero.
METHODS
new
new(token => $token, loop => $loop, intents => ['GUILDS']) returns a Gateway without I/O. loop is optional; otherwise one is created. Intents accept a bitmask or arrayref of names. Set intents for the events you need. rest and identify_limiter can inject caller-owned discovery resources. shard => [$id, $total] selects a shard.
connect
Discovers /gateway/bot, opens a verified TLS WebSocket and returns a Future resolving to the Gateway on READY or RESUMED. During reconnects, it waits for the next ready session. Cancelling it closes the Gateway.
completion
Returns the lifetime Future, resolving on orderly shutdown and failing on fatal errors.
close
Returns a Future waiting for transport shutdown. Cancels timers, writes and handlers. Repeated calls return the same Future. Injected REST clients and Identify limiters remain caller-owned.
on
on(EVENT => CODE) registers an event callback and returns the Gateway. Callbacks and failure handling are described under "EVENTS AND FAILURES".
send
send(opcode, data) returns a Future completing after the write, only while ready. Heartbeat, Identify and Resume are driver-managed. Payloads must fit 4096 bytes. The SDK limits traffic to 120 payloads per 60 seconds and reserves capacity for protocol traffic.
Cancelling removes an unsent write. Cancelling an active write resets the connection because delivery is uncertain. Application writes are not replayed.
state
Returns the connection state string.
loop
Returns the IO::Async::Loop.
session
Returns the internal protocol object. Use events for application work.
identify_limiter
Returns the internal Identify scheduler. Its API is not a public contract.
stats
Returns a hashref of counters, queue sizes and heartbeat latency.
EVENTS AND FAILURES
Event names are uppercase. Callbacks receive ($data, $gateway, $packet). on('*' => CODE) receives ($event, $data, $gateway, $packet). Unknown events and fields are preserved; unknown opcodes produce OPCODE with {op, d}.
Return handler Futures. Pending Futures do not delay heartbeats or incoming packets, but blocking Perl code blocks the loop. Thrown exceptions and failed Futures produce handler errors without stopping the connection.
on_error => CODE receives ($error, $gateway) synchronously. Without it, the SDK warns with a generic message. Errors omit raw frames, exceptions and credentials. Fatal close codes appear in close_code and stop reconnecting.
When the callback queue is full, the incoming event's application callbacks are dropped. Through Discord::Client, SDK cache and READY state updates and interaction dispatch occur before this queue and are preserved. Interaction dispatch still has its own bounded capacity. A queue_full error is reported once per saturation episode; stats counts all dropped_events and dropped_callbacks. Earlier work continues. Dropped events are not replayed; applications needing a complete stream must reconcile state. Each callback invocation uses capacity, even with a shared Future.
RECONNECTS AND IDENTIFY
The SDK schedules heartbeats from HELLO and reconnects if ACK is missing. Resume uses the saved URL, session ID and sequence. Non-resumable sessions Identify again; fatal close codes stop the driver. Reconnects use jittered backoff, reset after stable operation. Opcode 7 starts the first Resume attempt immediately. Compression is not requested.
shard => [$id, $total] selects a shard. Identify uses session-start metadata from /gateway/bot and a five-second cooldown per concurrency bucket. The cooldown starts when Identify is sent. Resume consumes no session start. Exhausted budgets wait for reset and refresh metadata. An exhausted budget with zero reset_after refreshes every second until starts or a positive delay become available. Heartbeats continue during Identify waits.
For several shards, use the shard manager. Identify coordination is local to one process; separate processes need external coordination.
OPTIONS
max_outgoing-
Queued and active writes; default 128.
max_events-
Queued callback invocations; default 1024.
max_handlers-
Pending callback invocations; default 64.
connect_timeout-
Seconds for connection/HELLO or sent authentication; default 30.
backoff_base-
Initial backoff in seconds; default 1.
backoff_max-
Maximum backoff in seconds; default 60.
stable_after-
Seconds before resetting backoff; default 60.
Identify waiting is excluded from the authentication timeout. stats returns counters, queue sizes and heartbeat latency. on_diagnostic receives synchronous events with state and reconnect timing, without raw payloads.
TRANSPORT INJECTION
websocket_factory receives loop, on_text and on_close. Its transport provides Future-returning connect($url), send($unicode_json), abort and close($code). Resolve connection before delivering text. abort stops I/O; close waits for cleanup. on_close supplies a numeric code without raw reason text. Pathless Gateway URLs use / for the handshake.
clock, delay, defer and random hooks allow deterministic tests. websocket_options => {tls => {...}} can supply a local test CA; peer and hostname verification remain enabled. The adapter accepts frames up to 16 MiB.
LICENSE
Apache License 2.0.