Browse Source

Don't throw if websocket close was requested

pull/501/head
RogueException 8 years ago
parent
commit
35c10a1006
2 changed files with 59 additions and 22 deletions
  1. +30
    -11
      src/Discord.Net.DebugTools/UnstableWebSocketClient.cs
  2. +29
    -11
      src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs

+ 30
- 11
src/Discord.Net.DebugTools/UnstableWebSocketClient.cs View File

@@ -28,7 +28,7 @@ namespace Discord.Net.Providers.UnstableWebSocket
private Task _task; private Task _task;
private CancellationTokenSource _cancelTokenSource; private CancellationTokenSource _cancelTokenSource;
private CancellationToken _cancelToken, _parentToken; private CancellationToken _cancelToken, _parentToken;
private bool _isDisposed;
private bool _isDisposed, _isDisconnecting;


public UnstableWebSocketClient() public UnstableWebSocketClient()
{ {
@@ -101,22 +101,44 @@ namespace Discord.Net.Providers.UnstableWebSocket
{ {
try { _cancelTokenSource.Cancel(false); } catch { } try { _cancelTokenSource.Cancel(false); } catch { }


if (!isDisposing)
_isDisconnecting = true;
try
{
await (_task ?? Task.Delay(0)).ConfigureAwait(false); await (_task ?? Task.Delay(0)).ConfigureAwait(false);
_task = null;
}
finally { _isDisconnecting = false; }


if (_client != null && _client.State == WebSocketState.Open)
if (_client != null)
{ {
var token = new CancellationToken();
if (!isDisposing) if (!isDisposing)
{ {
try { await _client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", token); }
try { await _client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", new CancellationToken()); }
catch { } catch { }
} }
try { _client.Dispose(); } try { _client.Dispose(); }
catch { } catch { }
_client = null; _client = null;
} }
} }
private async Task OnClosed(Exception ex)
{
if (_isDisconnecting)
return; //Ignore, this disconnect was requested.

System.Diagnostics.Debug.WriteLine("OnClosed - " + ex.Message);
await _lock.WaitAsync().ConfigureAwait(false);
try
{
await DisconnectInternalAsync(false);
}
finally
{
_lock.Release();
}
await Closed(ex);
}


public void SetHeader(string key, string value) public void SetHeader(string key, string value)
{ {
@@ -173,10 +195,7 @@ namespace Discord.Net.Providers.UnstableWebSocket
int resultCount; int resultCount;
if (socketResult.MessageType == WebSocketMessageType.Close) if (socketResult.MessageType == WebSocketMessageType.Close)
{
var _ = Closed(new WebSocketClosedException((int)socketResult.CloseStatus, socketResult.CloseStatusDescription));
return;
}
throw new WebSocketClosedException((int)socketResult.CloseStatus, socketResult.CloseStatusDescription);


if (!socketResult.EndOfMessage) if (!socketResult.EndOfMessage)
{ {
@@ -219,13 +238,13 @@ namespace Discord.Net.Providers.UnstableWebSocket
} }
catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT) catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT)
{ {
var _ = Closed(new Exception("Connection timed out.", ex));
var _ = OnClosed(new Exception("Connection timed out.", ex));
} }
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
catch (Exception ex) catch (Exception ex)
{ {
//This cannot be awaited otherwise we'll deadlock when DiscordApiClient waits for this task to complete. //This cannot be awaited otherwise we'll deadlock when DiscordApiClient waits for this task to complete.
var _ = Closed(ex);
var _ = OnClosed(ex);
} }
} }




+ 29
- 11
src/Discord.Net.WebSocket/Net/DefaultWebSocketClient.cs View File

@@ -26,7 +26,7 @@ namespace Discord.Net.WebSockets
private Task _task; private Task _task;
private CancellationTokenSource _cancelTokenSource; private CancellationTokenSource _cancelTokenSource;
private CancellationToken _cancelToken, _parentToken; private CancellationToken _cancelToken, _parentToken;
private bool _isDisposed;
private bool _isDisposed, _isDisconnecting;


public DefaultWebSocketClient() public DefaultWebSocketClient()
{ {
@@ -98,22 +98,43 @@ namespace Discord.Net.WebSockets
{ {
try { _cancelTokenSource.Cancel(false); } catch { } try { _cancelTokenSource.Cancel(false); } catch { }


if (!isDisposing)
_isDisconnecting = true;
try
{
await (_task ?? Task.Delay(0)).ConfigureAwait(false); await (_task ?? Task.Delay(0)).ConfigureAwait(false);
_task = null;
}
finally { _isDisconnecting = false; }


if (_client != null && _client.State == WebSocketState.Open)
if (_client != null)
{ {
var token = new CancellationToken();
if (!isDisposing) if (!isDisposing)
{ {
try { await _client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", token); }
try { await _client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", new CancellationToken()); }
catch { } catch { }
} }
try { _client.Dispose(); } try { _client.Dispose(); }
catch { } catch { }
_client = null; _client = null;
} }
} }
private async Task OnClosed(Exception ex)
{
if (_isDisconnecting)
return; //Ignore, this disconnect was requested.

await _lock.WaitAsync().ConfigureAwait(false);
try
{
await DisconnectInternalAsync(false);
}
finally
{
_lock.Release();
}
await Closed(ex);
}


public void SetHeader(string key, string value) public void SetHeader(string key, string value)
{ {
@@ -167,10 +188,7 @@ namespace Discord.Net.WebSockets
int resultCount; int resultCount;
if (socketResult.MessageType == WebSocketMessageType.Close) if (socketResult.MessageType == WebSocketMessageType.Close)
{
var _ = Closed(new WebSocketClosedException((int)socketResult.CloseStatus, socketResult.CloseStatusDescription));
return;
}
throw new WebSocketClosedException((int)socketResult.CloseStatus, socketResult.CloseStatusDescription);


if (!socketResult.EndOfMessage) if (!socketResult.EndOfMessage)
{ {
@@ -217,13 +235,13 @@ namespace Discord.Net.WebSockets
} }
catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT) catch (Win32Exception ex) when (ex.HResult == HR_TIMEOUT)
{ {
var _ = Closed(new Exception("Connection timed out.", ex));
var _ = OnClosed(new Exception("Connection timed out.", ex));
} }
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
catch (Exception ex) catch (Exception ex)
{ {
//This cannot be awaited otherwise we'll deadlock when DiscordApiClient waits for this task to complete. //This cannot be awaited otherwise we'll deadlock when DiscordApiClient waits for this task to complete.
var _ = Closed(ex);
var _ = OnClosed(ex);
} }
} }
} }


Loading…
Cancel
Save