feature: Implement gateway ratelimit (#1537)
* Implement gateway ratelimit * Remove unused code * Share WebSocketRequestQueue between clients * Add global limit and a way to change gateway limits * Refactoring variable to fit lib standards * Update xml docs * Update xml docs * Move warning to remarks * Remove specific RequestQueue for WebSocket and other changes The only account limit is for identify that is dealt in a different way (exclusive semaphore), so websocket queues can be shared with REST and don't need to be shared between clients anymore. Also added the ratelimit for presence updates. * Add summary to IdentifySemaphoreName * Fix spacing * Add max_concurrency and other fixes - Add session_start_limit to GetBotGatewayResponse - Add GetBotGatewayAsync to IDiscordClient - Add master/slave semaphores to enable concurrency - Not store semaphore name as static - Clone GatewayLimits when cloning the Config * Add missing RequestQueue parameter and wrong nullable * Add RequeueQueue paramater to Webhook * Better xml documentation * Remove GatewayLimits class and other changes - Remove GatewayLimits - Transfer a few properties to DiscordSocketConfig - Remove unnecessary usings * Remove unnecessary using and wording * Remove more unnecessary usings * Change named Semaphores to SemaphoreSlim * Remove unused using * Update branch * Fix merge conflicts and update to new ratelimit * Fixing merge, ignore limit for heartbeat, and dispose * Missed one place and better xml docs. * Wait identify before opening the connection * Only request identify ticket when needed * Move identify control to sharded client * Better description for IdentifyMaxConcurrency * Add lock to InvalidSession
This commit is contained in:
@@ -132,6 +132,8 @@ namespace Discord.API
|
||||
if (WebSocketClient == null)
|
||||
throw new NotSupportedException("This client is not configured with WebSocket support.");
|
||||
|
||||
RequestQueue.ClearGatewayBuckets();
|
||||
|
||||
//Re-create streams to reset the zlib state
|
||||
_compressed?.Dispose();
|
||||
_decompressor?.Dispose();
|
||||
@@ -205,7 +207,11 @@ namespace Discord.API
|
||||
payload = new SocketFrame { Operation = (int)opCode, Payload = payload };
|
||||
if (payload != null)
|
||||
bytes = Encoding.UTF8.GetBytes(SerializeJson(payload));
|
||||
await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, null, bytes, true, options)).ConfigureAwait(false);
|
||||
|
||||
options.IsGatewayBucket = true;
|
||||
if (options.BucketId == null)
|
||||
options.BucketId = GatewayBucket.Get(GatewayBucketType.Unbucketed).Id;
|
||||
await RequestQueue.SendAsync(new WebSocketRequest(WebSocketClient, bytes, true, opCode == GatewayOpCode.Heartbeat, options)).ConfigureAwait(false);
|
||||
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -225,6 +231,8 @@ namespace Discord.API
|
||||
if (totalShards > 1)
|
||||
msg.ShardingParams = new int[] { shardID, totalShards };
|
||||
|
||||
options.BucketId = GatewayBucket.Get(GatewayBucketType.Identify).Id;
|
||||
|
||||
if (gatewayIntents.HasValue)
|
||||
msg.Intents = (int)gatewayIntents.Value;
|
||||
else
|
||||
@@ -258,6 +266,7 @@ namespace Discord.API
|
||||
IsAFK = isAFK,
|
||||
Game = game
|
||||
};
|
||||
options.BucketId = GatewayBucket.Get(GatewayBucketType.PresenceUpdate).Id;
|
||||
await SendGatewayAsync(GatewayOpCode.StatusUpdate, args, options: options).ConfigureAwait(false);
|
||||
}
|
||||
public async Task SendRequestMembersAsync(IEnumerable<ulong> guildIds, RequestOptions options = null)
|
||||
|
||||
Reference in New Issue
Block a user