@@ -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;
}
}
}