DiscordPHP-Voice Documentation

WS
in package
implements GatewayCoordinatorHost uses HandlesDaveOpcodes

FinalYes

Handles the Discord voice WebSocket connection.

This class manages the WebSocket connection to the Discord voice gateway, handling events, sending messages, and managing the voice connection state.

Tags
since
10.19.0

Table of Contents

Interfaces

GatewayCoordinatorHost
Narrow interface exposing WS capabilities required by GatewayCoordinator.

Constants

MAX_DAVE_PROTOCOL_VERSION  : mixed = 1
The maximum DAVE protocol version supported.
VOICE_OP_HANDLERS  : array<int, string> = [\Discord\WebSockets\Op::VOICE_READY => 'handle...
Dispatch table mapping Discord Voice Gateway opcodes to handler methods.

Properties

$data  : array<string|int, mixed>|null
$mode  : string
The Voice WebSocket mode.
$ssrc  : null|string|int
The SSRC identifier for the voice connection client.
$vc  : Client
$daveState  : State
DAVE protocol state for this voice connection.
$discord  : Discord|null
$hbInterval  : mixed
The heartbeat interval for the voice connection.
$hbSequence  : int
The heartbeat sequence number.
$heartbeat  : TimerInterface
The heartbeat timer for the voice connection.
$maxDaveProtocolVersion  : int
Maximum supported DAVE protocol version for this runtime.
$rawKey  : array<string|int, mixed>|null
The raw secret key.
$secretKey  : string|null
The secret key used for encrypting voice.
$socket  : WebSocket
The WebSocket instance for the voice connection.
$udpfac  : SocketFactory
The SocketFactory instance for creating UDP sockets.
$version  : mixed
The Discord voice gateway version.
$coordinator  : GatewayCoordinator|null
The DAVE gateway coordinator for this voice connection.
$sentLoginFrame  : bool
Indicates whether the login frame has been sent.

Methods

__construct()  : mixed
The WebSocket connection for the voice client.
__debugInfo()  : array<string|int, mixed>
Redacts sensitive cryptographic material from debug output.
closeConnection()  : void
Closes the underlying WebSocket connection.
getDaveProtocolVersion()  : int
The active DAVE protocol version for this connection.
getDaveState()  : State
The per-connection {@see DaveState}.
getLogger()  : LoggerInterface
Returns the PSR-3 logger for this voice connection.
getMaxDaveProtocolVersion()  : int
Returns the maximum DAVE protocol version supported at runtime.
getVoiceClient()  : VoiceClient
Returns the VoiceClient associated with this connection.
handleAny()  : void
Handles the any event from the voice server.
handleClose()  : void
Handles the close event of the WebSocket connection.
handleCloseVoiceDisconnected()  : void
Handles a VOICE_DISCONNECTED close opcode (logs it; the reconnect path is driven elsewhere).
handleConnection()  : void
Handles a WebSocket connection.
handleHeartbeatAck()  : void
Handles the heartbeat acknowledgement from the voice WebSocket connection.
handleSendingOfLoginFrame()  : void
Handles sending the login frame to the voice WebSocket.
make()  : WS
Creates a new instance of the WS class.
send()  : void
Sends a message to the voice websocket.
sendDaveBinary()  : void
Sends a DAVE binary payload over the voice websocket.
sendHeartbeat()  : void
Sends a heartbeat to the voice WebSocket.
handleBinaryVoiceMessage()  : void
Handles binary voice websocket frames.
handleClientConnect()  : void
Handles the event when a client connects to the voice server.
handleClientDisconnect()  : void
Handles the event when a client disconnects from the voice server.
handleDaveExecuteTransition()  : void
Routes the VOICE_DAVE_EXECUTE_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveExecuteTransition()}.
handleDaveMlsAnnounceCommitTransition()  : void
Routes the VOICE_DAVE_MLS_ANNOUNCE_COMMIT_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsAnnounceCommitTransition()}.
handleDaveMlsCommitWelcome()  : void
Routes the VOICE_DAVE_MLS_COMMIT_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsCommitWelcome()}.
handleDaveMlsExternalSender()  : void
Routes the VOICE_DAVE_MLS_EXTERNAL_SENDER_PACKAGE opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsExternalSender()}.
handleDaveMlsInvalidCommitWelcome()  : void
Routes the VOICE_DAVE_MLS_INVALID_COMMIT_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsInvalidCommitWelcome()}.
handleDaveMlsKeyPackage()  : void
Handle an inbound opcode 26 (VOICE_DAVE_MLS_KEY_PACKAGE) frame from the gateway.
handleDaveMlsProposals()  : void
Routes the VOICE_DAVE_MLS_PROPOSALS opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsProposals()}.
handleDaveMlsWelcome()  : void
Routes the VOICE_DAVE_MLS_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsWelcome()}.
handleDavePrepareEpoch()  : void
Routes the VOICE_DAVE_PREPARE_EPOCH opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDavePrepareEpoch()}.
handleDavePrepareTransition()  : void
Routes the VOICE_DAVE_PREPARE_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDavePrepareTransition()}.
handleDaveTransitionReady()  : void
Routes the VOICE_DAVE_TRANSITION_READY opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveTransitionReady()}.
handleFlags()  : void
Handles the flags event from the voice server.
handleHello()  : void
Handles the "Hello" event from the Discord voice server.
handlePlatform()  : void
Handles the platform event from the voice server.
handleReady()  : void
Handles the "ready" event for the voice client, initializing UDP connection and heartbeat.
handleResume()  : void
Resumes a previously established voice connection.
handleResumed()  : void
Handles the 'resumed' event for the voice client.
handleSessionDescription()  : void
Handles the session description packet received from the Discord voice server.
handleSpeaking()  : void
Handles the speaking state of a user.
handleUndocumented()  : void
Handles undocumented voice opcodes not intended for use by bots.
extractProtocolVersion()  : int
getCoordinator()  : GatewayCoordinator
Returns the GatewayCoordinator, creating it lazily if needed.
initializeDaveRuntimeState()  : bool
Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::initializeDaveRuntimeState()}.
recordGatewaySequence()  : void
Records the last gateway sequence in the DAVE state and mirrors it into `$this->data['seq']` for resume.
resolveDaveGroupId()  : int|string|null
The MLS group id for this connection: the channel id, falling back to the guild id.
resolveDaveProtocolVersion()  : int
Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::resolveDaveProtocolVersion()}.
sendDaveKeyPackage()  : void
Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::sendDaveKeyPackage()}.

Constants

MAX_DAVE_PROTOCOL_VERSION

The maximum DAVE protocol version supported.

public mixed MAX_DAVE_PROTOCOL_VERSION = 1

VOICE_OP_HANDLERS

Dispatch table mapping Discord Voice Gateway opcodes to handler methods.

public array<int, string> VOICE_OP_HANDLERS = [\Discord\WebSockets\Op::VOICE_READY => 'handleReady', \Discord\WebSockets\Op::VOICE_SESSION_DESCRIPTION => 'handleSessionDescription', \Discord\WebSockets\Op::VOICE_SPEAKING => 'handleSpeaking', \Discord\WebSockets\Op::VOICE_HEARTBEAT_ACK => 'handleHeartbeatAck', \Discord\WebSockets\Op::VOICE_HELLO => 'handleHello', \Discord\WebSockets\Op::VOICE_RESUMED => 'handleResumed', \Discord\WebSockets\Op::VOICE_CLIENT_CONNECT => 'handleClientConnect', \Discord\WebSockets\Op::VOICE_CLIENT_DISCONNECT => 'handleClientDisconnect', \Discord\WebSockets\Op::VOICE_CLIENT_UNKNOWN_15 => 'handleAny', \Discord\WebSockets\Op::VOICE_CLIENT_UNKNOWN_18 => 'handleFlags', \Discord\WebSockets\Op::VOICE_CLIENT_PLATFORM => 'handlePlatform', \Discord\WebSockets\Op::VOICE_DAVE_PREPARE_TRANSITION => 'handleDavePrepareTransition', \Discord\WebSockets\Op::VOICE_DAVE_EXECUTE_TRANSITION => 'handleDaveExecuteTransition', \Discord\WebSockets\Op::VOICE_DAVE_PREPARE_EPOCH => 'handleDavePrepareEpoch', \Discord\WebSockets\Op::VOICE_DAVE_MLS_EXTERNAL_SENDER => 'handleDaveMlsExternalSender', \Discord\WebSockets\Op::VOICE_DAVE_MLS_PROPOSALS => 'handleDaveMlsProposals', \Discord\WebSockets\Op::VOICE_DAVE_MLS_ANNOUNCE_COMMIT_TRANSITION => 'handleDaveMlsAnnounceCommitTransition', \Discord\WebSockets\Op::VOICE_DAVE_MLS_WELCOME => 'handleDaveMlsWelcome', \Discord\WebSockets\Op::VOICE_DAVE_TRANSITION_READY => 'handleDaveTransitionReady', \Discord\WebSockets\Op::VOICE_DAVE_MLS_KEY_PACKAGE => 'handleDaveMlsKeyPackage', \Discord\WebSockets\Op::VOICE_DAVE_MLS_COMMIT_WELCOME => 'handleDaveMlsCommitWelcome', \Discord\WebSockets\Op::VOICE_DAVE_MLS_INVALID_COMMIT_WELCOME => 'handleDaveMlsInvalidCommitWelcome', \Discord\WebSockets\Op::CLOSE_VOICE_DISCONNECTED => 'handleCloseVoiceDisconnected']

Method name indexed by opcode constant.

Properties

$data

public array<string|int, mixed>|null $data = []

$ssrc

The SSRC identifier for the voice connection client.

public null|string|int $ssrc

$daveState

DAVE protocol state for this voice connection.

protected State $daveState

$discord

protected Discord|null $discord = null

$hbInterval

The heartbeat interval for the voice connection.

protected mixed $hbInterval

$hbSequence

The heartbeat sequence number.

protected int $hbSequence = 0

This is used to track the sequence of heartbeat messages sent to the voice gateway.

$heartbeat

The heartbeat timer for the voice connection.

protected TimerInterface $heartbeat

$maxDaveProtocolVersion

Maximum supported DAVE protocol version for this runtime.

protected int $maxDaveProtocolVersion = self::MAX_DAVE_PROTOCOL_VERSION

$rawKey

The raw secret key.

protected array<string|int, mixed>|null $rawKey

$secretKey

The secret key used for encrypting voice.

protected string|null $secretKey

$socket

The WebSocket instance for the voice connection.

protected WebSocket $socket

$udpfac

The SocketFactory instance for creating UDP sockets.

protected SocketFactory $udpfac

$coordinator

The DAVE gateway coordinator for this voice connection.

private GatewayCoordinator|null $coordinator = null

$sentLoginFrame

Indicates whether the login frame has been sent.

private bool $sentLoginFrame = false

Methods

__construct()

The WebSocket connection for the voice client.

public __construct(Client $vc[, Discord|null $discord = null ][, array<string|int, mixed>|null $data = [] ]) : mixed

This is used to send and receive messages over the WebSocket connection.

Parameters
$vc : Client
$discord : Discord|null = null
$data : array<string|int, mixed>|null = []

__debugInfo()

Redacts sensitive cryptographic material from debug output.

public __debugInfo() : array<string|int, mixed>
Return values
array<string|int, mixed>

closeConnection()

Closes the underlying WebSocket connection.

public closeConnection() : void

getDaveProtocolVersion()

The active DAVE protocol version for this connection.

public getDaveProtocolVersion() : int
Return values
int

getDaveState()

The per-connection {@see DaveState}.

public getDaveState() : State
Return values
State

getLogger()

Returns the PSR-3 logger for this voice connection.

public getLogger() : LoggerInterface
Return values
LoggerInterface

getMaxDaveProtocolVersion()

Returns the maximum DAVE protocol version supported at runtime.

public getMaxDaveProtocolVersion() : int
Return values
int

getVoiceClient()

Returns the VoiceClient associated with this connection.

public getVoiceClient() : VoiceClient
Return values
VoiceClient

handleAny()

Handles the any event from the voice server.

public handleAny(Payload $data) : void
Parameters
$data : Payload

handleClose()

Handles the close event of the WebSocket connection.

public handleClose(int $op, string $reason) : void
Parameters
$op : int

The opcode of the close event.

$reason : string

The reason for closing the connection.

handleCloseVoiceDisconnected()

Handles a VOICE_DISCONNECTED close opcode (logs it; the reconnect path is driven elsewhere).

public handleCloseVoiceDisconnected(Payload $data) : void
Parameters
$data : Payload

handleConnection()

Handles a WebSocket connection.

public handleConnection(WebSocket $ws) : void
Parameters
$ws : WebSocket

handleHeartbeatAck()

Handles the heartbeat acknowledgement from the voice WebSocket connection.

public handleHeartbeatAck(Payload $data) : void
Parameters
$data : Payload

make()

Creates a new instance of the WS class.

public static make(Client $vc[, null|Discord $discord = null ][, null|array<string|int, mixed> $data = null ]) : WS
Parameters
$vc : Client
$discord : null|Discord = null
$data : null|array<string|int, mixed> = null
Return values
WS

send()

Sends a message to the voice websocket.

public send(VoicePayload|array<string|int, mixed> $data) : void
Parameters
$data : VoicePayload|array<string|int, mixed>

sendDaveBinary()

Sends a DAVE binary payload over the voice websocket.

public sendDaveBinary(int $opcode[, string $payload = '' ]) : void
Parameters
$opcode : int
$payload : string = ''

sendHeartbeat()

Sends a heartbeat to the voice WebSocket.

public sendHeartbeat() : void

handleBinaryVoiceMessage()

Handles binary voice websocket frames.

protected handleBinaryVoiceMessage(string $payload) : void
Parameters
$payload : string

handleClientConnect()

Handles the event when a client connects to the voice server.

protected handleClientConnect(Payload $data) : void
Parameters
$data : Payload

handleClientDisconnect()

Handles the event when a client disconnects from the voice server.

protected handleClientDisconnect(Payload $data) : void
Parameters
$data : Payload

handleDaveExecuteTransition()

Routes the VOICE_DAVE_EXECUTE_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveExecuteTransition()}.

protected handleDaveExecuteTransition(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsAnnounceCommitTransition()

Routes the VOICE_DAVE_MLS_ANNOUNCE_COMMIT_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsAnnounceCommitTransition()}.

protected handleDaveMlsAnnounceCommitTransition(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsCommitWelcome()

Routes the VOICE_DAVE_MLS_COMMIT_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsCommitWelcome()}.

protected handleDaveMlsCommitWelcome(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsExternalSender()

Routes the VOICE_DAVE_MLS_EXTERNAL_SENDER_PACKAGE opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsExternalSender()}.

protected handleDaveMlsExternalSender(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsInvalidCommitWelcome()

Routes the VOICE_DAVE_MLS_INVALID_COMMIT_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsInvalidCommitWelcome()}.

protected handleDaveMlsInvalidCommitWelcome(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsKeyPackage()

Handle an inbound opcode 26 (VOICE_DAVE_MLS_KEY_PACKAGE) frame from the gateway.

protected handleDaveMlsKeyPackage(mixed $data) : void

Opcode 26 is primarily client→server: we send our own key package to the gateway via sendDaveKeyPackage() during the DAVE epoch-1 setup. The gateway may also forward a remote member's key package back to us as an informational notice — that is what this handler receives.

The gateway (server) is responsible for aggregating all key packages and driving the subsequent proposal/commit flow. We passively receive the forwarded package; no action is required on the client side.

Per the Discord DAVE spec: "Key packages are only used one time" — each time we need to join or rejoin a session we generate and send a fresh key package.

Parameters
$data : mixed

handleDaveMlsProposals()

Routes the VOICE_DAVE_MLS_PROPOSALS opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsProposals()}.

protected handleDaveMlsProposals(Payload $data) : void
Parameters
$data : Payload

handleDaveMlsWelcome()

Routes the VOICE_DAVE_MLS_WELCOME opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveMlsWelcome()}.

protected handleDaveMlsWelcome(Payload $data) : void
Parameters
$data : Payload

handleDavePrepareEpoch()

Routes the VOICE_DAVE_PREPARE_EPOCH opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDavePrepareEpoch()}.

protected handleDavePrepareEpoch(Payload $data) : void
Parameters
$data : Payload

handleDavePrepareTransition()

Routes the VOICE_DAVE_PREPARE_TRANSITION opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDavePrepareTransition()}.

protected handleDavePrepareTransition(Payload $data) : void
Parameters
$data : Payload

handleDaveTransitionReady()

Routes the VOICE_DAVE_TRANSITION_READY opcode to the {@see \Discord\Voice\Dave\GatewayCoordinator::handleDaveTransitionReady()}.

protected handleDaveTransitionReady(Payload $data) : void
Parameters
$data : Payload

handleFlags()

Handles the flags event from the voice server.

protected handleFlags(Payload $data) : void
Parameters
$data : Payload

handleHello()

Handles the "Hello" event from the Discord voice server.

protected handleHello(Payload $data) : void
Parameters
$data : Payload

handlePlatform()

Handles the platform event from the voice server.

protected handlePlatform(Payload $data) : void
Parameters
$data : Payload

handleReady()

Handles the "ready" event for the voice client, initializing UDP connection and heartbeat.

protected handleReady(Payload $data) : void
Parameters
$data : Payload

The data object containing voice server connection details:

  • $data->d['ssrc']: The synchronization source identifier.
  • $data->d['ip']: The IP address for the UDP connection.
  • $data->d['port']: The port for the UDP connection.
  • $data->d['modes']: Supported encryption modes.

handleResume()

Resumes a previously established voice connection.

protected handleResume() : void

handleResumed()

Handles the 'resumed' event for the voice client.

protected handleResumed(Payload $data) : void
Parameters
$data : Payload

handleSessionDescription()

Handles the session description packet received from the Discord voice server.

protected handleSessionDescription(Payload $data) : void
Parameters
$data : Payload

handleSpeaking()

Handles the speaking state of a user.

protected handleSpeaking(Payload $data) : void
Parameters
$data : Payload

The data object received from the WebSocket.

handleUndocumented()

Handles undocumented voice opcodes not intended for use by bots.

protected handleUndocumented(Payload $data) : void
Parameters
$data : Payload

extractProtocolVersion()

private extractProtocolVersion(array<string|int, mixed> $data) : int
Parameters
$data : array<string|int, mixed>
Return values
int

getCoordinator()

Returns the GatewayCoordinator, creating it lazily if needed.

private getCoordinator() : GatewayCoordinator

Lazy initialisation allows tests that bypass the constructor to still exercise DAVE methods without explicitly injecting the coordinator.

Return values
GatewayCoordinator

initializeDaveRuntimeState()

Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::initializeDaveRuntimeState()}.

private initializeDaveRuntimeState(int $protocolVersion[, bool $resetState = false ]) : bool
Parameters
$protocolVersion : int
$resetState : bool = false
Return values
bool

recordGatewaySequence()

Records the last gateway sequence in the DAVE state and mirrors it into `$this->data['seq']` for resume.

private recordGatewaySequence(int|null $sequence) : void
Parameters
$sequence : int|null

resolveDaveGroupId()

The MLS group id for this connection: the channel id, falling back to the guild id.

private resolveDaveGroupId() : int|string|null
Return values
int|string|null

resolveDaveProtocolVersion()

Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::resolveDaveProtocolVersion()}.

private resolveDaveProtocolVersion(int $protocolVersion) : int
Parameters
$protocolVersion : int
Return values
int

sendDaveKeyPackage()

Delegates to {@see \Discord\Voice\Dave\GatewayCoordinator::sendDaveKeyPackage()}.

private sendDaveKeyPackage() : void
On this page

Search results