protected override async Task ProcessMessage(string json)
{
await base.ProcessMessage(json).ConfigureAwait(false);
WebSocketMessage msg;
using (var reader = new JsonTextReader(new StringReader(json)))
msg = _serializer.Deserialize(reader, typeof(WebSocketMessage)) as WebSocketMessage;
var opCode = (OpCodes)msg.Operation;
switch (opCode)
{
case OpCodes.Ready:
{
if (State != ConnectionState.Connected)
{
var payload = (msg.Payload as JToken).ToObject<ReadyEvent>(_serializer);
_heartbeatInterval = payload.HeartbeatInterval;
_ssrc = payload.SSRC;
string hostname = Host.Replace("wss://", "");
var address = (await Dns.GetHostAddressesAsync(hostname).ConfigureAwait(false)).FirstOrDefault();
_endpoint = new IPEndPoint(address, payload.Port);
if (_audioConfig.EnableEncryption)
{
if (payload.Modes.Contains(EncryptedMode))
{
_encryptionMode = EncryptedMode;
_isEncrypted = true;
}
else
throw new InvalidOperationException("Unexpected encryption format.");
}
else
{
_encryptionMode = UnencryptedMode;
_isEncrypted = false;
}
_sequence = 0;// (ushort)_rand.Next(0, ushort.MaxValue);
//No thread issue here because SendAsync doesn't start until _isReady is true
byte[] packet = new byte[70];
packet[0] = (byte)(_ssrc >> 24);
packet[1] = (byte)(_ssrc >> 16);
packet[2] = (byte)(_ssrc >> 8);
packet[3] = (byte)(_ssrc >> 0);
await _udp.SendAsync(packet, 70, _endpoint).ConfigureAwait(false);
}
}
break;
case OpCodes.Heartbeat:
{
long time = EpochTime.GetMilliseconds();
var payload = (long)msg.Payload;
_ping = (int)(payload - time);
//TODO: Use this to estimate latency
}
break;
case OpCodes.SessionDescription:
{
var payload = (msg.Payload as JToken).ToObject<SessionDescriptionEvent>(_serializer);
_secretKey = payload.SecretKey;
SendSetSpeaking(true);
await EndConnect().ConfigureAwait(false);
}
break;
case OpCodes.Speaking:
{
var payload = (msg.Payload as JToken).ToObject<SpeakingEvent>(_serializer);
OnUserIsSpeaking(payload.UserId, payload.IsSpeaking);
}
break;
default:
Logger.Warning($"Unknown Opcode: {opCode}");
break;
}
}