Browse Source

Fixed a few websocket reconnect bugs

tags/docs-0.9
RogueException 9 years ago
parent
commit
56bf0fa254
3 changed files with 26 additions and 20 deletions
  1. +10
    -12
      src/Discord.Net/Net/WebSockets/BuiltInEngine.cs
  2. +2
    -2
      src/Discord.Net/Net/WebSockets/GatewaySocket.cs
  3. +14
    -6
      src/Discord.Net/Net/WebSockets/WS4NetEngine.cs

+ 10
- 12
src/Discord.Net/Net/WebSockets/BuiltInEngine.cs View File

@@ -21,6 +21,7 @@ namespace Discord.Net.WebSockets
private readonly DiscordConfig _config; private readonly DiscordConfig _config;
private readonly ConcurrentQueue<string> _sendQueue; private readonly ConcurrentQueue<string> _sendQueue;
private WebSocketClient _webSocket; private WebSocketClient _webSocket;
private Task _tempTask;


public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { }; public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { }; public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
@@ -35,18 +36,15 @@ namespace Discord.Net.WebSockets
_sendQueue = new ConcurrentQueue<string>(); _sendQueue = new ConcurrentQueue<string>();
} }


public Task Connect(string host, CancellationToken cancelToken)
public async Task Connect(string host, CancellationToken cancelToken)
{ {
return Task.Run(async () =>
{
_webSocket = new WebSocketClient();
_webSocket.Options.Proxy = null;
_webSocket.Options.SetRequestHeader("User-Agent", _config.UserAgent);
_webSocket.Options.KeepAliveInterval = TimeSpan.Zero;
await _webSocket.ConnectAsync(new Uri(host), cancelToken)//.ConfigureAwait(false);
.ContinueWith(t => ReceiveAsync(cancelToken)).ConfigureAwait(false);
//TODO: ContinueWith is a temporary hack, may be a bug related to https://github.com/dotnet/corefx/issues/4429
});
_webSocket = new WebSocketClient();
_webSocket.Options.Proxy = null;
_webSocket.Options.SetRequestHeader("User-Agent", _config.UserAgent);
_webSocket.Options.KeepAliveInterval = TimeSpan.Zero;
_tempTask = await _webSocket.ConnectAsync(new Uri(host), cancelToken)//.ConfigureAwait(false);
.ContinueWith(t => ReceiveAsync(cancelToken)).ConfigureAwait(false);
//TODO: ContinueWith is a temporary hack, may be a bug related to https://github.com/dotnet/corefx/issues/4429
} }


public Task Disconnect() public Task Disconnect()
@@ -61,7 +59,7 @@ namespace Discord.Net.WebSockets
} }


public IEnumerable<Task> GetTasks(CancellationToken cancelToken) public IEnumerable<Task> GetTasks(CancellationToken cancelToken)
=> new Task[] { /*ReceiveAsync(cancelToken),*/ SendAsync(cancelToken) };
=> new Task[] { /*ReceiveAsync(cancelToken),*/ _tempTask, SendAsync(cancelToken) };


private Task ReceiveAsync(CancellationToken cancelToken) private Task ReceiveAsync(CancellationToken cancelToken)
{ {


+ 2
- 2
src/Discord.Net/Net/WebSockets/GatewaySocket.cs View File

@@ -63,7 +63,7 @@ namespace Discord.Net.WebSockets
} }
catch (OperationCanceledException) { } catch (OperationCanceledException) { }
} }
public Task Disconnect() => _taskManager.Stop(true);
public Task Disconnect() => _taskManager.Stop();


protected override async Task Run() protected override async Task Run()
{ {
@@ -75,7 +75,7 @@ namespace Discord.Net.WebSockets
protected override Task Cleanup() protected override Task Cleanup()
{ {
var ex = _taskManager.Exception; var ex = _taskManager.Exception;
if (ex != null && (ex as WebSocketException)?.Code != 1012)
if (ex == null || (ex as WebSocketException)?.Code != 1012) //if (ex == null || (ex as WebSocketException)?.Code != 1012)
_sessionId = null; //Reset session unless close code 1012 _sessionId = null; //Reset session unless close code 1012
return base.Cleanup(); return base.Cleanup();
} }


+ 14
- 6
src/Discord.Net/Net/WebSockets/WS4NetEngine.cs View File

@@ -16,7 +16,7 @@ namespace Discord.Net.WebSockets
private readonly ConcurrentQueue<string> _sendQueue; private readonly ConcurrentQueue<string> _sendQueue;
private readonly TaskManager _taskManager; private readonly TaskManager _taskManager;
private WebSocketClient _webSocket; private WebSocketClient _webSocket;
private ManualResetEventSlim _waitUntilConnect;
private ManualResetEventSlim _waitUntilConnect, _waitUntilDisconnect;


public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { }; public event EventHandler<WebSocketBinaryMessageEventArgs> BinaryMessage = delegate { };
public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { }; public event EventHandler<WebSocketTextMessageEventArgs> TextMessage = delegate { };
@@ -31,6 +31,7 @@ namespace Discord.Net.WebSockets
_taskManager = taskManager; _taskManager = taskManager;
_sendQueue = new ConcurrentQueue<string>(); _sendQueue = new ConcurrentQueue<string>();
_waitUntilConnect = new ManualResetEventSlim(); _waitUntilConnect = new ManualResetEventSlim();
_waitUntilDisconnect = new ManualResetEventSlim(true);
} }


public Task Connect(string host, CancellationToken cancelToken) public Task Connect(string host, CancellationToken cancelToken)
@@ -62,13 +63,15 @@ namespace Discord.Net.WebSockets
_webSocket = null; _webSocket = null;
if (socket != null) if (socket != null)
{ {
//We dont want a slow disconnect to mess up the next connection, so lets just unregister events
socket.Close();
socket.Opened -= OnWebSocketOpened;
socket.DataReceived -= OnWebSocketBinary; socket.DataReceived -= OnWebSocketBinary;
socket.MessageReceived -= OnWebSocketText; socket.MessageReceived -= OnWebSocketText;

_waitUntilDisconnect.Wait(); //We need the next two events to raise this one
socket.Error -= OnWebSocketError; socket.Error -= OnWebSocketError;
socket.Closed -= OnWebSocketClosed; socket.Closed -= OnWebSocketClosed;
socket.Opened -= OnWebSocketOpened;
socket.Close();
socket.Dispose();
} }


return TaskHelper.CompletedTask; return TaskHelper.CompletedTask;
@@ -78,6 +81,7 @@ namespace Discord.Net.WebSockets
{ {
_taskManager.SignalError(e.Exception); _taskManager.SignalError(e.Exception);
_waitUntilConnect.Set(); _waitUntilConnect.Set();
_waitUntilDisconnect.Set();
} }
private void OnWebSocketClosed(object sender, EventArgs e) private void OnWebSocketClosed(object sender, EventArgs e)
{ {
@@ -85,12 +89,16 @@ namespace Discord.Net.WebSockets
if (e is ClosedEventArgs) if (e is ClosedEventArgs)
ex = new WebSocketException((e as ClosedEventArgs).Code, (e as ClosedEventArgs).Reason); ex = new WebSocketException((e as ClosedEventArgs).Code, (e as ClosedEventArgs).Reason);
else else
ex = new Exception($"Connection lost");
ex = new Exception("Connection lost");
_taskManager.SignalError(ex); _taskManager.SignalError(ex);
_waitUntilConnect.Set(); _waitUntilConnect.Set();
_waitUntilDisconnect.Set();
} }
private void OnWebSocketOpened(object sender, EventArgs e) private void OnWebSocketOpened(object sender, EventArgs e)
=> _waitUntilConnect.Set();
{
_waitUntilDisconnect.Reset();
_waitUntilConnect.Set();
}
private void OnWebSocketText(object sender, MessageReceivedEventArgs e) private void OnWebSocketText(object sender, MessageReceivedEventArgs e)
=> OnTextMessage(e.Message); => OnTextMessage(e.Message);
private void OnWebSocketBinary(object sender, DataReceivedEventArgs e) private void OnWebSocketBinary(object sender, DataReceivedEventArgs e)


Loading…
Cancel
Save