Voice stability patches

This commit is contained in:
RogueException
2015-09-23 22:42:25 -03:00
parent 7fa998a7c8
commit 454bd6f43d
5 changed files with 52 additions and 27 deletions

View File

@@ -15,20 +15,35 @@ namespace Discord
if (channelId == null) throw new ArgumentNullException(nameof(channelId)); if (channelId == null) throw new ArgumentNullException(nameof(channelId));
await LeaveVoiceServer().ConfigureAwait(false); await LeaveVoiceServer().ConfigureAwait(false);
try
{
await Task.Run(() =>
{
_voiceSocket.SetServer(serverId); _voiceSocket.SetServer(serverId);
_dataSocket.SendJoinVoice(serverId, channelId); _dataSocket.SendJoinVoice(serverId, channelId);
//await _voiceSocket.WaitForConnection().ConfigureAwait(false); _voiceSocket.WaitForConnection();
//TODO: Add another ManualResetSlim to wait on here, base it off of DiscordClient's setup })
.Timeout(_config.ConnectionTimeout)
.ConfigureAwait(false);
}
catch (TaskCanceledException)
{
await LeaveVoiceServer().ConfigureAwait(false);
}
} }
public async Task LeaveVoiceServer() public async Task LeaveVoiceServer()
{ {
CheckReady(checkVoice: true); CheckReady(checkVoice: true);
if (_voiceSocket.State != Net.WebSockets.WebSocketState.Disconnected) if (_voiceSocket.State != Net.WebSockets.WebSocketState.Disconnected)
{
var serverId = _voiceSocket.CurrentVoiceServerId;
if (serverId != null)
{ {
await _voiceSocket.Disconnect().ConfigureAwait(false); await _voiceSocket.Disconnect().ConfigureAwait(false);
await TaskHelper.CompletedTask.ConfigureAwait(false); _dataSocket.SendLeaveVoice(serverId);
_dataSocket.SendLeaveVoice(); }
} }
} }
@@ -57,7 +72,7 @@ namespace Discord
{ {
CheckReady(checkVoice: true); CheckReady(checkVoice: true);
_voiceSocket.Wait(); _voiceSocket.WaitForQueue();
await TaskHelper.CompletedTask.ConfigureAwait(false); await TaskHelper.CompletedTask.ConfigureAwait(false);
} }
} }

View File

@@ -32,11 +32,12 @@ namespace Discord
private readonly ManualResetEvent _disconnectedEvent; private readonly ManualResetEvent _disconnectedEvent;
private readonly ManualResetEventSlim _connectedEvent; private readonly ManualResetEventSlim _connectedEvent;
private readonly JsonSerializer _serializer; private readonly JsonSerializer _serializer;
protected ExceptionDispatchInfo _disconnectReason;
private Task _runTask; private Task _runTask;
private bool _wasDisconnectUnexpected;
private string _token; private string _token;
protected ExceptionDispatchInfo _disconnectReason;
private bool _wasDisconnectUnexpected;
/// <summary> Returns the id of the current logged-in user. </summary> /// <summary> Returns the id of the current logged-in user. </summary>
public string CurrentUserId => _currentUserId; public string CurrentUserId => _currentUserId;
private string _currentUserId; private string _currentUserId;
@@ -754,14 +755,14 @@ namespace Discord
//When the first task ends, make sure the rest do too //When the first task ends, make sure the rest do too
await DisconnectInternal(skipAwait: true); await DisconnectInternal(skipAwait: true);
bool wasUnexpected = _wasDisconnectUnexpected; await Cleanup().ConfigureAwait(false);
_wasDisconnectUnexpected = false;
await Cleanup(wasUnexpected).ConfigureAwait(false);
_runTask = null; _runTask = null;
} }
private async Task Cleanup(bool wasUnexpected) private async Task Cleanup()
{ {
var wasDisconnectUnexpected = _wasDisconnectUnexpected;
_wasDisconnectUnexpected = false;
await _dataSocket.Disconnect().ConfigureAwait(false); await _dataSocket.Disconnect().ConfigureAwait(false);
if (_config.EnableVoice) if (_config.EnableVoice)
await _voiceSocket.Disconnect().ConfigureAwait(false); await _voiceSocket.Disconnect().ConfigureAwait(false);
@@ -783,7 +784,7 @@ namespace Discord
_currentUserId = null; _currentUserId = null;
_token = null; _token = null;
if (!wasUnexpected) if (!wasDisconnectUnexpected)
{ {
_state = (int)DiscordClientState.Disconnected; _state = (int)DiscordClientState.Disconnected;
_disconnectedEvent.Set(); _disconnectedEvent.Set();

View File

@@ -119,9 +119,10 @@ namespace Discord.Net.WebSockets
joinVoice.Payload.ChannelId = channelId; joinVoice.Payload.ChannelId = channelId;
QueueMessage(joinVoice); QueueMessage(joinVoice);
} }
public void SendLeaveVoice() public void SendLeaveVoice(string serverId)
{ {
var leaveVoice = new Commands.JoinVoice(); var leaveVoice = new Commands.JoinVoice();
leaveVoice.Payload.ServerId = serverId;
QueueMessage(leaveVoice); QueueMessage(leaveVoice);
} }
} }

View File

@@ -514,9 +514,13 @@ namespace Discord.Net.WebSockets
return new VoiceCommands.KeepAlive(); return new VoiceCommands.KeepAlive();
} }
public void Wait() public void WaitForQueue()
{ {
_sendQueueEmptyWait.Wait(); _sendQueueEmptyWait.Wait(_cancelToken);
}
public void WaitForConnection()
{
_connectedEvent.Wait();
} }
} }
} }

View File

@@ -37,31 +37,33 @@ namespace Discord.Net.WebSockets
protected readonly IWebSocketEngine _engine; protected readonly IWebSocketEngine _engine;
protected readonly DiscordClient _client; protected readonly DiscordClient _client;
protected readonly LogMessageSeverity _logLevel; protected readonly LogMessageSeverity _logLevel;
protected readonly ManualResetEventSlim _connectedEvent;
public string Host { get; set; }
protected int _loginTimeout, _heartbeatInterval;
private DateTime _lastHeartbeat;
private Task _runTask;
public WebSocketState State => (WebSocketState)_state;
protected int _state;
protected ExceptionDispatchInfo _disconnectReason; protected ExceptionDispatchInfo _disconnectReason;
protected bool _wasDisconnectUnexpected; protected bool _wasDisconnectUnexpected;
protected WebSocketState _disconnectState; protected WebSocketState _disconnectState;
protected int _loginTimeout, _heartbeatInterval;
private DateTime _lastHeartbeat;
private Task _runTask;
public CancellationToken ParentCancelToken { get; set; } public CancellationToken ParentCancelToken { get; set; }
public CancellationToken CancelToken => _cancelToken; public CancellationToken CancelToken => _cancelToken;
private CancellationTokenSource _cancelTokenSource; private CancellationTokenSource _cancelTokenSource;
protected CancellationToken _cancelToken; protected CancellationToken _cancelToken;
public string Host { get; set; }
public WebSocketState State => (WebSocketState)_state;
protected int _state;
public WebSocket(DiscordClient client) public WebSocket(DiscordClient client)
{ {
_client = client; _client = client;
_logLevel = client.Config.LogLevel; _logLevel = client.Config.LogLevel;
_loginTimeout = client.Config.ConnectionTimeout; _loginTimeout = client.Config.ConnectionTimeout;
_cancelToken = new CancellationToken(true); _cancelToken = new CancellationToken(true);
_connectedEvent = new ManualResetEventSlim(false);
_engine = new BuiltInWebSocketEngine(client.Config.WebSocketInterval); _engine = new BuiltInWebSocketEngine(client.Config.WebSocketInterval);
_engine.ProcessMessage += async (s, e) => _engine.ProcessMessage += async (s, e) =>
@@ -102,6 +104,7 @@ namespace Discord.Net.WebSockets
protected void CompleteConnect() protected void CompleteConnect()
{ {
_state = (int)WebSocketState.Connected; _state = (int)WebSocketState.Connected;
_connectedEvent.Set();
RaiseConnected(); RaiseConnected();
} }
/*public Task Reconnect(CancellationToken cancelToken) /*public Task Reconnect(CancellationToken cancelToken)
@@ -184,6 +187,7 @@ namespace Discord.Net.WebSockets
var oldState = _state; var oldState = _state;
_state = (int)WebSocketState.Disconnected; _state = (int)WebSocketState.Disconnected;
_runTask = null; _runTask = null;
_connectedEvent.Reset();
if (disconnectState == WebSocketState.Connected) if (disconnectState == WebSocketState.Connected)
RaiseDisconnected(wasDisconnectUnexpected, _disconnectReason?.SourceException); RaiseDisconnected(wasDisconnectUnexpected, _disconnectReason?.SourceException);