Added better WebSocket disconnect support
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
@@ -12,6 +13,7 @@ namespace Discord
|
||||
{
|
||||
private const int ReceiveChunkSize = 4096;
|
||||
private const int SendChunkSize = 4096;
|
||||
private const int HR_TIMEOUT = -2147012894;
|
||||
|
||||
protected readonly DiscordClient _client;
|
||||
protected readonly int _sendInterval;
|
||||
@@ -90,7 +92,7 @@ namespace Discord
|
||||
{
|
||||
if (_task != null)
|
||||
{
|
||||
try { DisconnectInternal(new Exception("Disconnect requested by user.")); } catch (NullReferenceException) { }
|
||||
try { DisconnectInternal(new Exception("Disconnect requested by user."), false); } catch (NullReferenceException) { }
|
||||
try { await _task; } catch (NullReferenceException) { }
|
||||
}
|
||||
}
|
||||
@@ -99,12 +101,11 @@ namespace Discord
|
||||
{
|
||||
_disconnectToken.Cancel();
|
||||
}
|
||||
protected void DisconnectInternal(Exception ex)
|
||||
protected void DisconnectInternal(Exception ex, bool isUnexpected = true)
|
||||
{
|
||||
if (_disconnectReason == null)
|
||||
{
|
||||
if (ex == null)
|
||||
ex = new Exception("Disconnect requested by user.");
|
||||
_wasDisconnectUnexpected = isUnexpected;
|
||||
_disconnectReason = ex;
|
||||
_disconnectToken.Cancel();
|
||||
}
|
||||
@@ -141,14 +142,27 @@ namespace Discord
|
||||
{
|
||||
while (_webSocket.State == WebSocketState.Open && !cancelToken.IsCancellationRequested)
|
||||
{
|
||||
WebSocketReceiveResult result;
|
||||
WebSocketReceiveResult result = null;
|
||||
do
|
||||
{
|
||||
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancelToken);
|
||||
if (_webSocket.State != WebSocketState.Open || cancelToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), cancelToken);
|
||||
}
|
||||
catch (Win32Exception ex)
|
||||
when (ex.HResult == HR_TIMEOUT)
|
||||
{
|
||||
string msg = $"Connection timed out.";
|
||||
RaiseOnDebugMessage(DebugMessageType.Connection, msg);
|
||||
DisconnectInternal(new Exception(msg));
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
_wasDisconnectUnexpected = true;
|
||||
string msg = $"Got Close Message ({result.CloseStatus?.ToString() ?? "Unexpected"}, {result.CloseStatusDescription ?? "No Reason"})";
|
||||
RaiseOnDebugMessage(DebugMessageType.Connection, msg);
|
||||
DisconnectInternal(new Exception(msg));
|
||||
@@ -159,7 +173,7 @@ namespace Discord
|
||||
builder.Append(Encoding.UTF8.GetString(buffer, 0, result.Count));
|
||||
|
||||
}
|
||||
while (!result.EndOfMessage);
|
||||
while (result == null || !result.EndOfMessage);
|
||||
|
||||
#if DEBUG
|
||||
System.Diagnostics.Debug.WriteLine(">>> " + builder.ToString());
|
||||
@@ -235,8 +249,16 @@ namespace Discord
|
||||
count = message.Length - (i * SendChunkSize);
|
||||
else
|
||||
count = SendChunkSize;
|
||||
|
||||
await _webSocket.SendAsync(new ArraySegment<byte>(message, offset, count), WebSocketMessageType.Text, isLast, cancelToken);
|
||||
|
||||
try
|
||||
{
|
||||
await _webSocket.SendAsync(new ArraySegment<byte>(message, offset, count), WebSocketMessageType.Text, isLast, cancelToken);
|
||||
}
|
||||
catch (Win32Exception ex)
|
||||
when (ex.HResult == HR_TIMEOUT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user