Implemented resume_gateway_url. (#2423)
* Implemented resume_gateway_url. * Made the requested changes. * Implemented passing the gateway URL down from DiscordShardedClient. Co-authored-by: Quin Lynch <49576606+quinchs@users.noreply.github.com>
This commit is contained in:
@@ -20,6 +20,8 @@ namespace Discord.API.Gateway
|
|||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
[JsonProperty("session_id")]
|
[JsonProperty("session_id")]
|
||||||
public string SessionId { get; set; }
|
public string SessionId { get; set; }
|
||||||
|
[JsonProperty("resume_gateway_url")]
|
||||||
|
public string ResumeGatewayUrl { get; set; }
|
||||||
[JsonProperty("read_state")]
|
[JsonProperty("read_state")]
|
||||||
public ReadState[] ReadStates { get; set; }
|
public ReadState[] ReadStates { get; set; }
|
||||||
[JsonProperty("guilds")]
|
[JsonProperty("guilds")]
|
||||||
|
|||||||
@@ -139,9 +139,9 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
internal override async Task OnLoginAsync(TokenType tokenType, string token)
|
internal override async Task OnLoginAsync(TokenType tokenType, string token)
|
||||||
{
|
{
|
||||||
|
var botGateway = await GetBotGatewayAsync().ConfigureAwait(false);
|
||||||
if (_automaticShards)
|
if (_automaticShards)
|
||||||
{
|
{
|
||||||
var botGateway = await GetBotGatewayAsync().ConfigureAwait(false);
|
|
||||||
_shardIds = Enumerable.Range(0, botGateway.Shards).ToArray();
|
_shardIds = Enumerable.Range(0, botGateway.Shards).ToArray();
|
||||||
_totalShards = _shardIds.Length;
|
_totalShards = _shardIds.Length;
|
||||||
_shards = new DiscordSocketClient[_shardIds.Length];
|
_shards = new DiscordSocketClient[_shardIds.Length];
|
||||||
@@ -163,7 +163,12 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
//Assume thread safe: already in a connection lock
|
//Assume thread safe: already in a connection lock
|
||||||
for (int i = 0; i < _shards.Length; i++)
|
for (int i = 0; i < _shards.Length; i++)
|
||||||
|
{
|
||||||
|
// Set the gateway URL to the one returned by Discord, if a custom one isn't set.
|
||||||
|
_shards[i].ApiClient.GatewayUrl = botGateway.Url;
|
||||||
|
|
||||||
await _shards[i].LoginAsync(tokenType, token);
|
await _shards[i].LoginAsync(tokenType, token);
|
||||||
|
}
|
||||||
|
|
||||||
if(_defaultStickers.Length == 0 && _baseConfig.AlwaysDownloadDefaultStickers)
|
if(_defaultStickers.Length == 0 && _baseConfig.AlwaysDownloadDefaultStickers)
|
||||||
await DownloadDefaultStickersAsync().ConfigureAwait(false);
|
await DownloadDefaultStickersAsync().ConfigureAwait(false);
|
||||||
@@ -175,8 +180,13 @@ namespace Discord.WebSocket
|
|||||||
if (_shards != null)
|
if (_shards != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _shards.Length; i++)
|
for (int i = 0; i < _shards.Length; i++)
|
||||||
|
{
|
||||||
|
// Reset the gateway URL set for the shard.
|
||||||
|
_shards[i].ApiClient.GatewayUrl = null;
|
||||||
|
|
||||||
await _shards[i].LogoutAsync();
|
await _shards[i].LogoutAsync();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_automaticShards)
|
if (_automaticShards)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace Discord.API
|
|||||||
private readonly bool _isExplicitUrl;
|
private readonly bool _isExplicitUrl;
|
||||||
private CancellationTokenSource _connectCancelToken;
|
private CancellationTokenSource _connectCancelToken;
|
||||||
private string _gatewayUrl;
|
private string _gatewayUrl;
|
||||||
|
private string _resumeGatewayUrl;
|
||||||
|
|
||||||
//Store our decompression streams for zlib shared state
|
//Store our decompression streams for zlib shared state
|
||||||
private MemoryStream _compressed;
|
private MemoryStream _compressed;
|
||||||
@@ -37,6 +38,32 @@ namespace Discord.API
|
|||||||
|
|
||||||
public ConnectionState ConnectionState { get; private set; }
|
public ConnectionState ConnectionState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the gateway URL used for identifies.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If a custom URL is set, setting this property does nothing.
|
||||||
|
/// </remarks>
|
||||||
|
public string GatewayUrl
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// Makes the sharded client not override the custom value.
|
||||||
|
if (_isExplicitUrl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_gatewayUrl = FormatGatewayUrl(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the gateway URL used for resumes.
|
||||||
|
/// </summary>
|
||||||
|
public string ResumeGatewayUrl
|
||||||
|
{
|
||||||
|
set => _resumeGatewayUrl = FormatGatewayUrl(value);
|
||||||
|
}
|
||||||
|
|
||||||
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent,
|
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent,
|
||||||
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
|
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
|
||||||
bool useSystemClock = true, Func<IRateLimitInfo, Task> defaultRatelimitCallback = null)
|
bool useSystemClock = true, Func<IRateLimitInfo, Task> defaultRatelimitCallback = null)
|
||||||
@@ -157,6 +184,17 @@ namespace Discord.API
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Appends necessary query parameters to the specified gateway URL.
|
||||||
|
/// </summary>
|
||||||
|
private static string FormatGatewayUrl(string gatewayUrl)
|
||||||
|
{
|
||||||
|
if (gatewayUrl == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return $"{gatewayUrl}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}&compress=zlib-stream";
|
||||||
|
}
|
||||||
|
|
||||||
public async Task ConnectAsync()
|
public async Task ConnectAsync()
|
||||||
{
|
{
|
||||||
await _stateLock.WaitAsync().ConfigureAwait(false);
|
await _stateLock.WaitAsync().ConfigureAwait(false);
|
||||||
@@ -191,24 +229,32 @@ namespace Discord.API
|
|||||||
if (WebSocketClient != null)
|
if (WebSocketClient != null)
|
||||||
WebSocketClient.SetCancelToken(_connectCancelToken.Token);
|
WebSocketClient.SetCancelToken(_connectCancelToken.Token);
|
||||||
|
|
||||||
if (!_isExplicitUrl)
|
string gatewayUrl;
|
||||||
|
if (_resumeGatewayUrl == null)
|
||||||
{
|
{
|
||||||
var gatewayResponse = await GetGatewayAsync().ConfigureAwait(false);
|
if (!_isExplicitUrl && _gatewayUrl == null)
|
||||||
_gatewayUrl = $"{gatewayResponse.Url}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}&compress=zlib-stream";
|
{
|
||||||
|
var gatewayResponse = await GetBotGatewayAsync().ConfigureAwait(false);
|
||||||
|
_gatewayUrl = FormatGatewayUrl(gatewayResponse.Url);
|
||||||
|
}
|
||||||
|
|
||||||
|
gatewayUrl = _gatewayUrl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gatewayUrl = _resumeGatewayUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG_PACKETS
|
#if DEBUG_PACKETS
|
||||||
Console.WriteLine("Connecting to gateway: " + _gatewayUrl);
|
Console.WriteLine("Connecting to gateway: " + gatewayUrl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
await WebSocketClient.ConnectAsync(_gatewayUrl).ConfigureAwait(false);
|
await WebSocketClient.ConnectAsync(gatewayUrl).ConfigureAwait(false);
|
||||||
|
|
||||||
ConnectionState = ConnectionState.Connected;
|
ConnectionState = ConnectionState.Connected;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
if (!_isExplicitUrl)
|
|
||||||
_gatewayUrl = null; //Uncache in case the gateway url changed
|
|
||||||
await DisconnectInternalAsync().ConfigureAwait(false);
|
await DisconnectInternalAsync().ConfigureAwait(false);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,7 +322,6 @@ namespace Discord.WebSocket
|
|||||||
}
|
}
|
||||||
private async Task OnDisconnectingAsync(Exception ex)
|
private async Task OnDisconnectingAsync(Exception ex)
|
||||||
{
|
{
|
||||||
|
|
||||||
await _gatewayLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false);
|
await _gatewayLogger.DebugAsync("Disconnecting ApiClient").ConfigureAwait(false);
|
||||||
await ApiClient.DisconnectAsync(ex).ConfigureAwait(false);
|
await ApiClient.DisconnectAsync(ex).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -353,6 +352,10 @@ namespace Discord.WebSocket
|
|||||||
if (guild.IsAvailable)
|
if (guild.IsAvailable)
|
||||||
await GuildUnavailableAsync(guild).ConfigureAwait(false);
|
await GuildUnavailableAsync(guild).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sessionId = null;
|
||||||
|
_lastSeq = 0;
|
||||||
|
ApiClient.ResumeGatewayUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -834,6 +837,7 @@ namespace Discord.WebSocket
|
|||||||
|
|
||||||
_sessionId = null;
|
_sessionId = null;
|
||||||
_lastSeq = 0;
|
_lastSeq = 0;
|
||||||
|
ApiClient.ResumeGatewayUrl = null;
|
||||||
|
|
||||||
if (_shardedClient != null)
|
if (_shardedClient != null)
|
||||||
{
|
{
|
||||||
@@ -891,6 +895,7 @@ namespace Discord.WebSocket
|
|||||||
AddPrivateChannel(data.PrivateChannels[i], state);
|
AddPrivateChannel(data.PrivateChannels[i], state);
|
||||||
|
|
||||||
_sessionId = data.SessionId;
|
_sessionId = data.SessionId;
|
||||||
|
ApiClient.ResumeGatewayUrl = data.ResumeGatewayUrl;
|
||||||
_unavailableGuildCount = unavailableGuilds;
|
_unavailableGuildCount = unavailableGuilds;
|
||||||
CurrentUser = currentUser;
|
CurrentUser = currentUser;
|
||||||
_previousSessionUser = CurrentUser;
|
_previousSessionUser = CurrentUser;
|
||||||
|
|||||||
Reference in New Issue
Block a user