| @@ -1,5 +1,4 @@ | |||
| #define USE_THREAD | |||
| using Discord.API; | |||
| using Discord.API; | |||
| using Discord.Audio; | |||
| using Newtonsoft.Json; | |||
| using Newtonsoft.Json.Linq; | |||
| @@ -36,10 +35,8 @@ namespace Discord.Net.WebSockets | |||
| private byte[] _secretKey, _encodingBuffer; | |||
| private ushort _sequence; | |||
| private string _serverId, _channelId, _userId, _sessionId, _token, _encryptionMode; | |||
| #if USE_THREAD | |||
| private Thread _sendThread, _receiveThread; | |||
| #endif | |||
| public string CurrentServerId => _serverId; | |||
| public string CurrentChannelId => _channelId; | |||
| @@ -109,9 +106,6 @@ namespace Discord.Net.WebSockets | |||
| protected override IEnumerable<Task> GetTasks() | |||
| { | |||
| _udp = new UdpClient(new IPEndPoint(IPAddress.Any, 0)); | |||
| #if !DNX451 && !__MonoCS__ | |||
| _udp.AllowNatTraversal(true); | |||
| #endif | |||
| VoiceLoginCommand msg = new VoiceLoginCommand(); | |||
| msg.Payload.ServerId = _serverId; | |||
| @@ -123,16 +117,11 @@ namespace Discord.Net.WebSockets | |||
| List<Task> tasks = new List<Task>(); | |||
| if ((_client.Config.VoiceMode & DiscordVoiceMode.Outgoing) != 0) | |||
| { | |||
| #if USE_THREAD | |||
| _sendThread = new Thread(new ThreadStart(() => SendVoiceAsync(_cancelToken))); | |||
| _sendThread.IsBackground = true; | |||
| _sendThread.Start(); | |||
| #else | |||
| tasks.Add(SendVoiceAsync()); | |||
| #endif | |||
| } | |||
| #if USE_THREAD | |||
| //This thread is required to establish a connection even if we're outgoing only | |||
| if ((_client.Config.VoiceMode & DiscordVoiceMode.Incoming) != 0) | |||
| { | |||
| @@ -142,9 +131,6 @@ namespace Discord.Net.WebSockets | |||
| } | |||
| else //Dont make an OS thread if we only want to capture one packet... | |||
| tasks.Add(Task.Run(() => ReceiveVoiceAsync(_cancelToken))); | |||
| #else | |||
| tasks.Add(ReceiveVoiceAsync()); | |||
| #endif | |||
| tasks.Add(WatcherAsync()); | |||
| if (tasks.Count > 0) | |||
| @@ -162,14 +148,12 @@ namespace Discord.Net.WebSockets | |||
| } | |||
| protected override Task Cleanup() | |||
| { | |||
| #if USE_THREAD | |||
| if (_sendThread != null) | |||
| _sendThread.Join(); | |||
| if (_receiveThread != null) | |||
| _receiveThread.Join(); | |||
| _sendThread = null; | |||
| _receiveThread = null; | |||
| #endif | |||
| OpusDecoder decoder; | |||
| foreach (var pair in _decoders) | |||
| @@ -189,18 +173,9 @@ namespace Discord.Net.WebSockets | |||
| return base.Cleanup(); | |||
| } | |||
| #if USE_THREAD | |||
| private void ReceiveVoiceAsync(CancellationToken cancelToken) | |||
| { | |||
| #else | |||
| private Task ReceiveVoiceAsync() | |||
| { | |||
| var cancelToken = _cancelToken; | |||
| return Task.Run(async () => | |||
| { | |||
| #endif | |||
| try | |||
| { | |||
| byte[] packet, decodingBuffer = null, nonce = null, result; | |||
| @@ -215,20 +190,10 @@ namespace Discord.Net.WebSockets | |||
| while (!cancelToken.IsCancellationRequested) | |||
| { | |||
| #if USE_THREAD | |||
| Thread.Sleep(1); | |||
| #elif DNXCORE50 | |||
| await Task.Delay(1).ConfigureAwait(false); | |||
| #endif | |||
| #if USE_THREAD || DNXCORE50 | |||
| if (_udp.Available > 0) | |||
| { | |||
| packet = _udp.Receive(ref endpoint); | |||
| #else | |||
| var msg = await _udp.ReceiveAsync().ConfigureAwait(false); | |||
| endpoint = msg.Endpoint; | |||
| receievedPacket = msg.Buffer; | |||
| #endif | |||
| packetLength = packet.Length; | |||
| if (packetLength > 0 && endpoint.Equals(_endpoint)) | |||
| @@ -304,40 +269,19 @@ namespace Discord.Net.WebSockets | |||
| RaiseOnPacket(userId, _channelId, result, resultOffset, resultLength); | |||
| } | |||
| } | |||
| #if USE_THREAD || DNXCORE50 | |||
| } | |||
| #endif | |||
| } | |||
| } | |||
| catch (OperationCanceledException) { } | |||
| catch (InvalidOperationException) { } //Includes ObjectDisposedException | |||
| #if !USE_THREAD | |||
| }).ConfigureAwait(false); | |||
| #endif | |||
| } | |||
| #if USE_THREAD | |||
| private void SendVoiceAsync(CancellationToken cancelToken) | |||
| { | |||
| #else | |||
| private Task SendVoiceAsync() | |||
| { | |||
| var cancelToken = _cancelToken; | |||
| return Task.Run(async () => | |||
| { | |||
| #endif | |||
| try | |||
| { | |||
| while (!cancelToken.IsCancellationRequested && _state != (int)WebSocketState.Connected) | |||
| { | |||
| #if USE_THREAD | |||
| Thread.Sleep(1); | |||
| #else | |||
| await Task.Delay(1); | |||
| #endif | |||
| } | |||
| if (cancelToken.IsCancellationRequested) | |||
| return; | |||
| @@ -406,11 +350,7 @@ namespace Discord.Net.WebSockets | |||
| Buffer.BlockCopy(encodedFrame, 0, udpPacket, 12, encodedLength); | |||
| rtpPacketLength = encodedLength + 12; | |||
| } | |||
| #if USE_THREAD | |||
| _udp.Send(udpPacket, rtpPacketLength); | |||
| #else | |||
| await _udp.SendAsync(rtpPacket, rtpPacketLength).ConfigureAwait(false); | |||
| #endif | |||
| } | |||
| timestamp = unchecked(timestamp + samplesPerFrame); | |||
| nextTicks += ticksPerFrame; | |||
| @@ -420,29 +360,12 @@ namespace Discord.Net.WebSockets | |||
| else if (ticksToNextFrame > spinLockThreshold) | |||
| { | |||
| int time = (int)Math.Ceiling((ticksToNextFrame - spinLockThreshold) / ticksPerMillisecond); | |||
| #if USE_THREAD | |||
| Thread.Sleep(1); | |||
| #else | |||
| await Task.Delay(1).ConfigureAwait(false); | |||
| #endif | |||
| } | |||
| //Don't spinlock if we're not actually sending audio (or buffer underrunning) | |||
| /*else if (_sendQueue.Count == 0) | |||
| { | |||
| int time = (int)Math.Ceiling(ticksToNextFrame / ticksPerMillisecond); | |||
| #if USE_THREAD | |||
| Thread.Sleep(1); | |||
| #else | |||
| await Task.Delay(1).ConfigureAwait(false); | |||
| #endif | |||
| }*/ | |||
| } | |||
| } | |||
| catch (OperationCanceledException) { } | |||
| catch (InvalidOperationException) { } //Includes ObjectDisposedException | |||
| #if !USE_THREAD | |||
| }).ConfigureAwait(false); | |||
| #endif | |||
| } | |||
| //Closes the UDP socket when _disconnectToken is triggered, since UDPClient doesn't allow passing a canceltoken | |||
| private Task WatcherAsync() | |||