diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index a4d8d2e03..ed5e6e2b5 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -224,6 +224,7 @@ namespace Discord ClientAPI.Token = token; GatewaySocket.Token = token; + GatewaySocket.SessionId = null; //Get gateway and check token try @@ -274,6 +275,7 @@ namespace Discord await GatewaySocket.Disconnect(); ClientAPI.Token = null; GatewaySocket.Token = null; + GatewaySocket.SessionId = null; _servers.Clear(); _channels.Clear(); @@ -468,6 +470,8 @@ namespace Discord case "READY": { var data = e.Payload.ToObject(_serializer); + GatewaySocket.StartHeartbeat(data.HeartbeatInterval); + GatewaySocket.SessionId = data.SessionId; SessionId = data.SessionId; PrivateUser = new User(this, data.User.Id, null); PrivateUser.Update(data.User); @@ -488,6 +492,12 @@ namespace Discord } } break; + case "RESUMED": + { + var data = e.Payload.ToObject(_serializer); + GatewaySocket.StartHeartbeat(data.HeartbeatInterval); + } + break; //Servers case "GUILD_CREATE": @@ -1004,9 +1014,6 @@ namespace Discord case "GUILD_EMOJIS_UPDATE": break; - case "RESUMED": //Handled in DataWebSocket - break; - //Others default: Logger.Warning($"Unknown message type: {e.Type}"); diff --git a/src/Discord.Net/Models/Profile.cs b/src/Discord.Net/Models/Profile.cs index 33bd6f059..6c8f327e3 100644 --- a/src/Discord.Net/Models/Profile.cs +++ b/src/Discord.Net/Models/Profile.cs @@ -57,6 +57,7 @@ namespace Discord var loginResponse = await Client.ClientAPI.Send(loginRequest).ConfigureAwait(false); Client.ClientAPI.Token = loginResponse.Token; Client.GatewaySocket.Token = loginResponse.Token; + Client.GatewaySocket.SessionId = null; } } diff --git a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs index b5c6d18e4..f7f6040bc 100644 --- a/src/Discord.Net/Net/WebSockets/GatewaySocket.cs +++ b/src/Discord.Net/Net/WebSockets/GatewaySocket.cs @@ -13,11 +13,10 @@ namespace Discord.Net.WebSockets public sealed class GatewaySocket : WebSocket { private uint _lastSequence; - private string _sessionId; - private string _token; private int _reconnects; - public string Token { get { return _token; } internal set { _token = value; _sessionId = null; } } + public string Token { get; internal set; } + public string SessionId { get; internal set; } public event EventHandler ReceivedDispatch = delegate { }; private void OnReceivedDispatch(string type, JToken payload) @@ -36,7 +35,7 @@ namespace Discord.Net.WebSockets public async Task Connect() { await BeginConnect().ConfigureAwait(false); - if (_sessionId == null) + if (SessionId == null) SendIdentify(Token); else SendResume(); @@ -81,7 +80,7 @@ namespace Discord.Net.WebSockets { var ex = _taskManager.Exception; 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(); } @@ -97,22 +96,12 @@ namespace Discord.Net.WebSockets { case OpCodes.Dispatch: { - JToken token = msg.Payload as JToken; - if (msg.Type == "READY") - { + OnReceivedDispatch(msg.Type, msg.Payload as JToken); + if (msg.Type == "READY" || msg.Type == "RESUMED") + { _reconnects = 0; - var payload = token.ToObject(_serializer); - _sessionId = payload.SessionId; - _heartbeatInterval = payload.HeartbeatInterval; - } - else if (msg.Type == "RESUMED") - { - var payload = token.ToObject(_serializer); - _heartbeatInterval = payload.HeartbeatInterval; - } - OnReceivedDispatch(msg.Type, token); - if (msg.Type == "READY" || msg.Type == "RESUMED") - EndConnect(); //Complete the connect + EndConnect(); //Complete the connect + } } break; case OpCodes.Redirect: @@ -153,7 +142,7 @@ namespace Discord.Net.WebSockets } public void SendResume() - => QueueMessage(new ResumeCommand { SessionId = _sessionId, Sequence = _lastSequence }); + => QueueMessage(new ResumeCommand { SessionId = SessionId, Sequence = _lastSequence }); public override void SendHeartbeat() => QueueMessage(new HeartbeatCommand()); public void SendUpdateStatus(long? idleSince, string gameName) @@ -167,6 +156,11 @@ namespace Discord.Net.WebSockets public void SendRequestMembers(ulong serverId, string query, int limit) => QueueMessage(new RequestMembersCommand { GuildId = serverId, Query = query, Limit = limit }); + internal void StartHeartbeat(int interval) + { + _heartbeatInterval = interval; + } + //Cancel if either DiscordClient.Disconnect is called, data socket errors or timeout is reached public override void WaitForConnection(CancellationToken cancelToken) => base.WaitForConnection(CancellationTokenSource.CreateLinkedTokenSource(cancelToken, CancelToken).Token);