From 46dc18dd4caba22634ce133f6b20d06df035e8f7 Mon Sep 17 00:00:00 2001 From: kozabrada123 <59031733+kozabrada123@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:02:15 +0100 Subject: [PATCH] fix: implement gateway Reconnect and InvalidSession --- src/gateway/events.rs | 2 ++ src/gateway/gateway.rs | 41 ++++++++++++++++++++++++++--- src/types/events/invalid_session.rs | 17 ++++++++++++ src/types/events/mod.rs | 4 +++ src/types/events/reconnect.rs | 12 +++++++++ 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/types/events/invalid_session.rs create mode 100644 src/types/events/reconnect.rs diff --git a/src/gateway/events.rs b/src/gateway/events.rs index cf074bd..8d38cca 100644 --- a/src/gateway/events.rs +++ b/src/gateway/events.rs @@ -46,6 +46,8 @@ pub struct Session { pub ready: GatewayEvent, pub ready_supplemental: GatewayEvent, pub replace: GatewayEvent, + pub reconnect: GatewayEvent, + pub invalid: GatewayEvent, } #[derive(Default, Debug)] diff --git a/src/gateway/gateway.rs b/src/gateway/gateway.rs index 29218b0..231590e 100644 --- a/src/gateway/gateway.rs +++ b/src/gateway/gateway.rs @@ -14,8 +14,9 @@ use super::*; use super::{Sink, Stream}; use crate::types::{ self, AutoModerationRule, AutoModerationRuleUpdate, Channel, ChannelCreate, ChannelDelete, - ChannelUpdate, Guild, GuildRoleCreate, GuildRoleUpdate, JsonField, RoleObject, SourceUrlField, - ThreadUpdate, UpdateMessage, WebSocketEvent, + ChannelUpdate, GatewayInvalidSession, GatewayReconnect, Guild, GuildRoleCreate, + GuildRoleUpdate, JsonField, RoleObject, SourceUrlField, ThreadUpdate, UpdateMessage, + WebSocketEvent, }; #[derive(Debug)] @@ -338,10 +339,42 @@ impl Gateway { .unwrap(); } GATEWAY_RECONNECT => { - todo!() + trace!("GW: Received Reconnect"); + + let reconnect = GatewayReconnect {}; + + self.events + .lock() + .await + .session + .reconnect + .notify(reconnect) + .await; } GATEWAY_INVALID_SESSION => { - todo!() + trace!("GW: Received Invalid Session"); + + let mut resumable: bool = false; + + if let Some(raw_value) = gateway_payload.event_data { + if let Ok(deserialized) = serde_json::from_str(raw_value.get()) { + resumable = deserialized; + } else { + warn!("Failed to parse part of INVALID_SESSION ('{}' as bool), assuming non-resumable", raw_value.get()); + } + } else { + warn!("Failed to parse part of INVALID_SESSION ('d' missing), assuming non-resumable"); + } + + let invalid_session = GatewayInvalidSession { resumable }; + + self.events + .lock() + .await + .session + .invalid + .notify(invalid_session) + .await; } // Starts our heartbeat // We should have already handled this in gateway init diff --git a/src/types/events/invalid_session.rs b/src/types/events/invalid_session.rs new file mode 100644 index 0000000..ae61879 --- /dev/null +++ b/src/types/events/invalid_session.rs @@ -0,0 +1,17 @@ +use serde::{Deserialize, Serialize}; + +use super::WebSocketEvent; + +#[derive(Debug, Deserialize, Serialize, Default, Clone)] +/// Your session is now invalid. +/// +/// Either reauthenticate and reidentify or resume if possible. +/// +/// # Reference +/// See +pub struct GatewayInvalidSession { + #[serde(rename = "d")] + pub resumable: bool, +} + +impl WebSocketEvent for GatewayInvalidSession {} diff --git a/src/types/events/mod.rs b/src/types/events/mod.rs index 66749ca..6faafd1 100644 --- a/src/types/events/mod.rs +++ b/src/types/events/mod.rs @@ -14,12 +14,14 @@ pub use hello::*; pub use identify::*; pub use integration::*; pub use interaction::*; +pub use invalid_session::*; pub use invite::*; pub use lazy_request::*; pub use message::*; pub use passive_update::*; pub use presence::*; pub use ready::*; +pub use reconnect::*; pub use relationship::*; pub use request_members::*; pub use resume::*; @@ -60,12 +62,14 @@ mod hello; mod identify; mod integration; mod interaction; +mod invalid_session; mod invite; mod lazy_request; mod message; mod passive_update; mod presence; mod ready; +mod reconnect; mod relationship; mod request_members; mod resume; diff --git a/src/types/events/reconnect.rs b/src/types/events/reconnect.rs new file mode 100644 index 0000000..d2751cc --- /dev/null +++ b/src/types/events/reconnect.rs @@ -0,0 +1,12 @@ +use serde::{Deserialize, Serialize}; + +use super::WebSocketEvent; + +#[derive(Debug, Deserialize, Serialize, Default, Clone)] +/// "The reconnect event is dispatched when a client should reconnect to the Gateway (and resume their existing session, if they have one). This event usually occurs during deploys to migrate sessions gracefully off old hosts" +/// +/// # Reference +/// See +pub struct GatewayReconnect {} + +impl WebSocketEvent for GatewayReconnect {}