private ValueTask <bool> TryProcessOpcodeAsync(
            ref VoiceGatewayPayload payload,
            CancellationToken cancellationToken = default)
        {
            switch (payload.Opcode)
            {
            case VoiceGatewayOpcode.Hello:
            {
                _heartbeatInterval = payload.Hello.HeartbeatInterval;
                _ = _heartbeatMutex.Release();

                return(SendIdentifyAsync(cancellationToken));
            }

            case VoiceGatewayOpcode.Ready:
            {
                if (!Utf8IpAddressUtilities.TryParseAddress(
                        payload.Ready.SlicedIp, out var address))
                {
                    return(new ValueTask <bool>(false));
                }

                var remote = new IPEndPoint(address, payload.Ready.Port);
                ClientSsrcUpdated?.Invoke(this, payload.Ready.Ssrc);
                Ssrc = payload.Ready.Ssrc;
                RemoteEndPointUpdated?.Invoke(this, remote);
                EndPoint = remote;

                return(ClientEndPoint != null
                        ? SendSelectProtocolAsync(
                           payload.Ready, cancellationToken)
                        : HandleTaskAsync(
                           PerformDiscoveryAndSelectProtocolAsync(
                               payload.Ready, cancellationToken)));
            }

            case VoiceGatewayOpcode.SessionDescription:
            {
                SessionEncryptionKeyUpdated?.Invoke(this,
                                                    _sessionEncryptionKey.Memory.Slice(0,
                                                                                       SessionEncryptionKeyLength));

                Ready?.Invoke(this, null !);
                return(new ValueTask <bool>(true));
            }

            case VoiceGatewayOpcode.HeartbeatAck:
            {
                Debug.Assert(_nonce == payload.Nonce + 1,
                             "Nonces didn't match");
                return(new ValueTask <bool>(true));
            }
            }

            return(new ValueTask <bool>(false));
        private ValueTask <bool> TryProcessPacketAsync(
            ref ReadOnlySequence <byte> sequence,
            CancellationToken cancellationToken = default)
        {
            var reader = new Utf8JsonReader(sequence);

            VoiceGatewayPayload payload = default;

            if (!Payload.TryReadOpcode(ref reader, out payload.Opcode))
            {
                return(new ValueTask <bool>(false));
            }

            switch (payload.Opcode)
            {
            case VoiceGatewayOpcode.Hello:
            {
                if (!Payload.TryReadHello(ref reader, out payload.Hello))
                {
                    return(new ValueTask <bool>(false));
                }

                break;
            }

            case VoiceGatewayOpcode.Ready:
            {
                if (!Payload.TryReadReady(ref reader, out payload.Ready))
                {
                    return(new ValueTask <bool>(false));
                }

                break;
            }

            case VoiceGatewayOpcode.SessionDescription:
            {
                if (!Payload.TryReadSessionDescription(ref reader,
                                                       _sessionEncryptionKey.Memory.Span.Slice(0,
                                                                                               SessionEncryptionKeyLength)))
                {
                    return(new ValueTask <bool>(false));
                }

                break;
            }

            case VoiceGatewayOpcode.HeartbeatAck:
            {
                if (!Payload.TryReadHeartbeatAck(ref reader,
                                                 out payload.Nonce))
                {
                    return(new ValueTask <bool>(false));
                }

                break;
            }

            case VoiceGatewayOpcode.Speaking:
            {
                return(new ValueTask <bool>(reader.TrySkip()));
            }

            default:
            {
                return(new ValueTask <bool>(reader.TrySkip()));
            }
            }

            if (!reader.TryReadToken(JsonTokenType.EndObject))
            {
                return(new ValueTask <bool>(false));
            }

            sequence = sequence.Slice(reader.Position);

            _logger.LogTrace("Received opcode {Opcode}", payload.Opcode);

            return(TryProcessOpcodeAsync(ref payload, cancellationToken));
        }