Added connection timeout. Dont require a lock to abort a failed connection attempt.
This commit is contained in:
@@ -6,7 +6,6 @@ using Discord.Rest;
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@@ -21,9 +20,13 @@ namespace Discord.Rpc
|
|||||||
private CancellationTokenSource _cancelToken, _reconnectCancelToken;
|
private CancellationTokenSource _cancelToken, _reconnectCancelToken;
|
||||||
private Task _reconnectTask;
|
private Task _reconnectTask;
|
||||||
private bool _canReconnect;
|
private bool _canReconnect;
|
||||||
|
private int _connectionTimeout;
|
||||||
|
|
||||||
public ConnectionState ConnectionState { get; private set; }
|
public ConnectionState ConnectionState { get; private set; }
|
||||||
|
|
||||||
|
//From DiscordRpcConfig
|
||||||
|
internal int ConnectionTimeout { get; private set; }
|
||||||
|
|
||||||
public new API.DiscordRpcApiClient ApiClient => base.ApiClient as API.DiscordRpcApiClient;
|
public new API.DiscordRpcApiClient ApiClient => base.ApiClient as API.DiscordRpcApiClient;
|
||||||
|
|
||||||
/// <summary> Creates a new RPC discord client. </summary>
|
/// <summary> Creates a new RPC discord client. </summary>
|
||||||
@@ -32,6 +35,7 @@ namespace Discord.Rpc
|
|||||||
public DiscordRpcClient(DiscordRpcConfig config)
|
public DiscordRpcClient(DiscordRpcConfig config)
|
||||||
: base(config, CreateApiClient(config))
|
: base(config, CreateApiClient(config))
|
||||||
{
|
{
|
||||||
|
ConnectionTimeout = config.ConnectionTimeout;
|
||||||
_rpcLogger = LogManager.CreateLogger("RPC");
|
_rpcLogger = LogManager.CreateLogger("RPC");
|
||||||
|
|
||||||
_serializer = new JsonSerializer { ContractResolver = new DiscordContractResolver() };
|
_serializer = new JsonSerializer { ContractResolver = new DiscordContractResolver() };
|
||||||
@@ -95,8 +99,17 @@ namespace Discord.Rpc
|
|||||||
await _rpcLogger.InfoAsync("Connecting").ConfigureAwait(false);
|
await _rpcLogger.InfoAsync("Connecting").ConfigureAwait(false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_connectTask = new TaskCompletionSource<bool>();
|
var connectTask = new TaskCompletionSource<bool>();
|
||||||
|
_connectTask = connectTask;
|
||||||
_cancelToken = new CancellationTokenSource();
|
_cancelToken = new CancellationTokenSource();
|
||||||
|
|
||||||
|
//Abort connection on timeout
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(_connectionTimeout);
|
||||||
|
connectTask.TrySetException(new TimeoutException());
|
||||||
|
});
|
||||||
|
|
||||||
await ApiClient.ConnectAsync().ConfigureAwait(false);
|
await ApiClient.ConnectAsync().ConfigureAwait(false);
|
||||||
await _connectedEvent.InvokeAsync().ConfigureAwait(false);
|
await _connectedEvent.InvokeAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,12 @@ namespace Discord.Rpc
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets or sets the Discord client/application id used for this RPC connection. </summary>
|
/// <summary> Gets or sets the Discord client/application id used for this RPC connection. </summary>
|
||||||
public string ClientId { get; set; }
|
public string ClientId { get; }
|
||||||
/// <summary> Gets or sets the origin used for this RPC connection. </summary>
|
/// <summary> Gets or sets the origin used for this RPC connection. </summary>
|
||||||
public string Origin { get; set; }
|
public string Origin { get; }
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the time, in milliseconds, to wait for a connection to complete before aborting. </summary>
|
||||||
|
public int ConnectionTimeout { get; set; } = 30000;
|
||||||
|
|
||||||
/// <summary> Gets or sets the provider used to generate new websocket connections. </summary>
|
/// <summary> Gets or sets the provider used to generate new websocket connections. </summary>
|
||||||
public WebSocketProvider WebSocketProvider { get; set; } = () => new DefaultWebSocketClient();
|
public WebSocketProvider WebSocketProvider { get; set; } = () => new DefaultWebSocketClient();
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace Discord.WebSocket
|
|||||||
internal int LargeThreshold { get; private set; }
|
internal int LargeThreshold { get; private set; }
|
||||||
internal AudioMode AudioMode { get; private set; }
|
internal AudioMode AudioMode { get; private set; }
|
||||||
internal DataStore DataStore { get; private set; }
|
internal DataStore DataStore { get; private set; }
|
||||||
|
internal int ConnectionTimeout { get; private set; }
|
||||||
internal WebSocketProvider WebSocketProvider { get; private set; }
|
internal WebSocketProvider WebSocketProvider { get; private set; }
|
||||||
|
|
||||||
public new API.DiscordSocketApiClient ApiClient => base.ApiClient as API.DiscordSocketApiClient;
|
public new API.DiscordSocketApiClient ApiClient => base.ApiClient as API.DiscordSocketApiClient;
|
||||||
@@ -70,6 +71,7 @@ namespace Discord.WebSocket
|
|||||||
LargeThreshold = config.LargeThreshold;
|
LargeThreshold = config.LargeThreshold;
|
||||||
AudioMode = config.AudioMode;
|
AudioMode = config.AudioMode;
|
||||||
WebSocketProvider = config.WebSocketProvider;
|
WebSocketProvider = config.WebSocketProvider;
|
||||||
|
ConnectionTimeout = config.ConnectionTimeout;
|
||||||
|
|
||||||
DataStore = new DataStore(0, 0);
|
DataStore = new DataStore(0, 0);
|
||||||
_nextAudioId = 1;
|
_nextAudioId = 1;
|
||||||
@@ -158,8 +160,17 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_connectTask = new TaskCompletionSource<bool>();
|
var connectTask = new TaskCompletionSource<bool>();
|
||||||
|
_connectTask = connectTask;
|
||||||
_cancelToken = new CancellationTokenSource();
|
_cancelToken = new CancellationTokenSource();
|
||||||
|
|
||||||
|
//Abort connection on timeout
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
await Task.Delay(ConnectionTimeout);
|
||||||
|
connectTask.TrySetException(new TimeoutException());
|
||||||
|
});
|
||||||
|
|
||||||
await ApiClient.ConnectAsync().ConfigureAwait(false);
|
await ApiClient.ConnectAsync().ConfigureAwait(false);
|
||||||
await _connectedEvent.InvokeAsync().ConfigureAwait(false);
|
await _connectedEvent.InvokeAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -249,6 +260,15 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
private async Task StartReconnectAsync(Exception ex)
|
private async Task StartReconnectAsync(Exception ex)
|
||||||
{
|
{
|
||||||
|
if (ex == null)
|
||||||
|
{
|
||||||
|
if (_connectTask?.TrySetCanceled() ?? false) return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_connectTask?.TrySetException(ex) ?? false) return;
|
||||||
|
}
|
||||||
|
|
||||||
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
await _connectionLock.WaitAsync().ConfigureAwait(false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -260,15 +280,6 @@ namespace Discord.WebSocket
|
|||||||
}
|
}
|
||||||
private async Task ReconnectInternalAsync(Exception ex, CancellationToken cancelToken)
|
private async Task ReconnectInternalAsync(Exception ex, CancellationToken cancelToken)
|
||||||
{
|
{
|
||||||
if (ex == null)
|
|
||||||
{
|
|
||||||
if (_connectTask?.TrySetCanceled() ?? false) return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (_connectTask?.TrySetException(ex) ?? false) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Random jitter = new Random();
|
Random jitter = new Random();
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ namespace Discord.WebSocket
|
|||||||
{
|
{
|
||||||
public const string GatewayEncoding = "json";
|
public const string GatewayEncoding = "json";
|
||||||
|
|
||||||
|
/// <summary> Gets or sets the time, in milliseconds, to wait for a connection to complete before aborting. </summary>
|
||||||
|
public int ConnectionTimeout { get; set; } = 30000;
|
||||||
|
|
||||||
/// <summary> Gets or sets the id for this shard. Must be less than TotalShards. </summary>
|
/// <summary> Gets or sets the id for this shard. Must be less than TotalShards. </summary>
|
||||||
public int ShardId { get; set; } = 0;
|
public int ShardId { get; set; } = 0;
|
||||||
/// <summary> Gets or sets the total number of shards for this application. </summary>
|
/// <summary> Gets or sets the total number of shards for this application. </summary>
|
||||||
@@ -16,8 +19,7 @@ namespace Discord.WebSocket
|
|||||||
/// <summary> Gets or sets the number of messages per channel that should be kept in cache. Setting this to zero disables the message cache entirely. </summary>
|
/// <summary> Gets or sets the number of messages per channel that should be kept in cache. Setting this to zero disables the message cache entirely. </summary>
|
||||||
public int MessageCacheSize { get; set; } = 0;
|
public int MessageCacheSize { get; set; } = 0;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the max number of users a guild may have for offline users to be included in the READY packet. Max is 250.
|
/// Gets or sets the max number of users a guild may have for offline users to be included in the READY packet. Max is 250.
|
||||||
/// Decreasing this may reduce CPU usage while increasing login time and network usage.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int LargeThreshold { get; set; } = 250;
|
public int LargeThreshold { get; set; } = 250;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user