Browse Source

Added better WebSocket disconnect support

tags/docs-0.9
Brandon Smith 9 years ago
parent
commit
61644d1f77
1 changed files with 32 additions and 10 deletions
  1. +32
    -10
      src/Discord.Net/DiscordWebSocket.cs

+ 32
- 10
src/Discord.Net/DiscordWebSocket.cs View File

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



Loading…
Cancel
Save