Fixed reconnect crash
This commit is contained in:
@@ -95,7 +95,7 @@ namespace Discord
|
||||
_api = new DiscordAPIClient(_config.LogLevel);
|
||||
_dataSocket = new DataWebSocket(this);
|
||||
_dataSocket.Connected += (s, e) => { if (_state == (int)DiscordClientState.Connecting) CompleteConnect(); };
|
||||
_dataSocket.Disconnected += async (s, e) => { RaiseDisconnected(e); if (e.WasUnexpected) await Connect(_token); /*await _dataSocket.Reconnect(_cancelToken);*/ };
|
||||
_dataSocket.Disconnected += async (s, e) => { RaiseDisconnected(e); if (e.WasUnexpected) await Reconnect(_token); };
|
||||
if (_config.EnableVoice)
|
||||
{
|
||||
_voiceSocket = new VoiceWebSocket(this);
|
||||
@@ -553,7 +553,8 @@ namespace Discord
|
||||
/// <summary> Connects to the Discord server with the provided token. </summary>
|
||||
public async Task Connect(string token)
|
||||
{
|
||||
await Disconnect().ConfigureAwait(false);
|
||||
if (_state != (int)DiscordClientState.Disconnected)
|
||||
await Disconnect().ConfigureAwait(false);
|
||||
|
||||
if (_config.LogLevel >= LogMessageSeverity.Verbose)
|
||||
RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Authentication, $"Using cached token.");
|
||||
@@ -564,7 +565,8 @@ namespace Discord
|
||||
/// <returns> Returns a token for future connections. </returns>
|
||||
public async Task<string> Connect(string email, string password)
|
||||
{
|
||||
await Disconnect().ConfigureAwait(false);
|
||||
if (_state != (int)DiscordClientState.Disconnected)
|
||||
await Disconnect().ConfigureAwait(false);
|
||||
|
||||
var response = await _api.Login(email, password).ConfigureAwait(false);
|
||||
if (_config.LogLevel >= LogMessageSeverity.Verbose)
|
||||
@@ -572,11 +574,15 @@ namespace Discord
|
||||
|
||||
return await ConnectInternal(response.Token).ConfigureAwait(false);
|
||||
}
|
||||
private Task Reconnect(string token)
|
||||
{
|
||||
if (_config.LogLevel >= LogMessageSeverity.Verbose)
|
||||
RaiseOnLog(LogMessageSeverity.Verbose, LogMessageSource.Authentication, $"Using cached token.");
|
||||
|
||||
return ConnectInternal(token);
|
||||
}
|
||||
private async Task<string> ConnectInternal(string token)
|
||||
{
|
||||
if (_state != (int)DiscordClientState.Disconnected)
|
||||
throw new InvalidOperationException("Client is already connected or connecting to the server.");
|
||||
|
||||
try
|
||||
{
|
||||
_disconnectedEvent.Reset();
|
||||
@@ -618,14 +624,14 @@ namespace Discord
|
||||
}
|
||||
protected void CompleteConnect()
|
||||
{
|
||||
_state = (int)WebSocketState.Connected;
|
||||
_state = (int)DiscordClientState.Connected;
|
||||
_connectedEvent.Set();
|
||||
RaiseConnected();
|
||||
}
|
||||
|
||||
/// <summary> Disconnects from the Discord server, canceling any pending requests. </summary>
|
||||
public Task Disconnect() => DisconnectInternal(new Exception("Disconnect was requested by user."), isUnexpected: false);
|
||||
protected Task DisconnectInternal(Exception ex, bool isUnexpected = true, bool skipAwait = false)
|
||||
protected Task DisconnectInternal(Exception ex = null, bool isUnexpected = true, bool skipAwait = false)
|
||||
{
|
||||
int oldState;
|
||||
bool hasWriterLock;
|
||||
@@ -644,7 +650,7 @@ namespace Discord
|
||||
if (hasWriterLock)
|
||||
{
|
||||
_wasDisconnectUnexpected = isUnexpected;
|
||||
_disconnectReason = ExceptionDispatchInfo.Capture(ex);
|
||||
_disconnectReason = ex != null ? ExceptionDispatchInfo.Capture(ex) : null;
|
||||
_cancelTokenSource.Cancel();
|
||||
}
|
||||
|
||||
@@ -662,12 +668,12 @@ namespace Discord
|
||||
else
|
||||
task = _cancelToken.Wait();
|
||||
|
||||
try
|
||||
{
|
||||
await task.ConfigureAwait(false);
|
||||
}
|
||||
try { await task.ConfigureAwait(false); }
|
||||
catch (Exception ex) { await DisconnectInternal(ex, skipAwait: true).ConfigureAwait(false); }
|
||||
|
||||
//When the first task ends, make sure the rest do too
|
||||
await DisconnectInternal(skipAwait: true);
|
||||
|
||||
bool wasUnexpected = _wasDisconnectUnexpected;
|
||||
_wasDisconnectUnexpected = false;
|
||||
|
||||
@@ -680,8 +686,11 @@ namespace Discord
|
||||
if (_config.EnableVoice)
|
||||
await _voiceSocket.Disconnect().ConfigureAwait(false);
|
||||
|
||||
Message ignored;
|
||||
while (_pendingMessages.TryDequeue(out ignored)) { }
|
||||
if (_config.UseMessageQueue)
|
||||
{
|
||||
Message ignored;
|
||||
while (_pendingMessages.TryDequeue(out ignored)) { }
|
||||
}
|
||||
|
||||
_channels.Clear();
|
||||
_members.Clear();
|
||||
|
||||
@@ -70,6 +70,29 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
await Connect(host, cancelToken);
|
||||
}
|
||||
public async Task Reconnect(CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Connect(_host, cancelToken).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseOnLog(LogMessageSeverity.Error, $"DataSocket reconnect failed: {ex.GetBaseException().Message}");
|
||||
//Net is down? We can keep trying to reconnect until the user runs Disconnect()
|
||||
await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
}
|
||||
|
||||
protected override Task[] Run()
|
||||
{
|
||||
|
||||
@@ -69,29 +69,6 @@ namespace Discord.Net.WebSockets
|
||||
};
|
||||
}
|
||||
|
||||
public async Task Reconnect(CancellationToken cancelToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Delay(_client.Config.ReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Connect(_host, cancelToken).ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
catch (OperationCanceledException) { throw; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
RaiseOnLog(LogMessageSeverity.Error, $"DataSocket reconnect failed: {ex.GetBaseException().Message}");
|
||||
//Net is down? We can keep trying to reconnect until the user runs Disconnect()
|
||||
await Task.Delay(_client.Config.FailedReconnectDelay, cancelToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) { }
|
||||
}
|
||||
protected virtual async Task Connect(string host, CancellationToken cancelToken)
|
||||
{
|
||||
if (_state != (int)WebSocketState.Disconnected)
|
||||
@@ -127,7 +104,7 @@ namespace Discord.Net.WebSockets
|
||||
=> Connect(_host, _cancelToken);*/
|
||||
|
||||
public Task Disconnect() => DisconnectInternal(new Exception("Disconnect was requested by user."), isUnexpected: false);
|
||||
protected Task DisconnectInternal(Exception ex, bool isUnexpected = true, bool skipAwait = false)
|
||||
protected Task DisconnectInternal(Exception ex = null, bool isUnexpected = true, bool skipAwait = false)
|
||||
{
|
||||
int oldState;
|
||||
bool hasWriterLock;
|
||||
@@ -146,7 +123,7 @@ namespace Discord.Net.WebSockets
|
||||
if (hasWriterLock)
|
||||
{
|
||||
_wasDisconnectUnexpected = isUnexpected;
|
||||
_disconnectReason = ExceptionDispatchInfo.Capture(ex);
|
||||
_disconnectReason = ex != null ? ExceptionDispatchInfo.Capture(ex) : null;
|
||||
_cancelTokenSource.Cancel();
|
||||
}
|
||||
|
||||
@@ -158,13 +135,17 @@ namespace Discord.Net.WebSockets
|
||||
|
||||
protected virtual async Task RunTasks()
|
||||
{
|
||||
Task task = Task.WhenAll(Run());
|
||||
Task[] tasks = Run();
|
||||
Task firstTask = Task.WhenAny(tasks);
|
||||
Task allTasks = Task.WhenAll(tasks);
|
||||
|
||||
try
|
||||
{
|
||||
await task.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex) { await DisconnectInternal(ex, skipAwait: true).ConfigureAwait(false); }
|
||||
try { await firstTask.ConfigureAwait(false); }
|
||||
catch (Exception ex) { await DisconnectInternal(ex: ex, skipAwait: true).ConfigureAwait(false); }
|
||||
|
||||
//When the first task ends, make sure the rest do too
|
||||
await DisconnectInternal(skipAwait: true);
|
||||
try { await allTasks.ConfigureAwait(false); }
|
||||
catch { }
|
||||
|
||||
bool wasUnexpected = _wasDisconnectUnexpected;
|
||||
_wasDisconnectUnexpected = false;
|
||||
@@ -207,7 +188,7 @@ namespace Discord.Net.WebSockets
|
||||
{
|
||||
while (!cancelToken.IsCancellationRequested)
|
||||
{
|
||||
if (_heartbeatInterval > 0)
|
||||
if (_state == (int)WebSocketState.Connected)
|
||||
{
|
||||
QueueMessage(GetKeepAlive());
|
||||
await Task.Delay(_heartbeatInterval, cancelToken).ConfigureAwait(false);
|
||||
|
||||
Reference in New Issue
Block a user