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)); }