diff --git a/DiscordClient.js b/DiscordClient.js index 24e722e..6b5b2fe 100644 --- a/DiscordClient.js +++ b/DiscordClient.js @@ -7,18 +7,17 @@ const opcodes = { EVENT: 0, CLIENT_HEARTBEAT: 1, IDENTIFY: 2, - RESUME: 6, INVALID_SESSION: 9, HELLO: 10, HEARTBEAT_ACK: 11, }; -const reconnectOnCloseCodes = [ - 1000, 1001, 4000, 4001, 4002, 4003, 4005, 4007, 4008, 4009 +const skipReconnectFor = [ + 4004, 4010, 4011, 4012, 4013, 4014 ]; class DiscordClient extends EventEmitter { - constructor(token, { intents, baseDomain="discord.com", gatewayUrl="wss://gateway.discord.gg/?v=9&encoding=json&compress=zlib-stream", apiBase="https://discord.com/api/v9" } = {}) { + constructor(token, { intents, gatewayUrl="wss://gateway.discord.gg/?v=9&encoding=json&compress=zlib-stream", apiBase="https://discord.com/api/v9" } = {}) { super(); this.token = token; @@ -79,19 +78,11 @@ class DiscordClient extends EventEmitter { }; } - _getResumePayload() { - return { - token: this.token, - session_id: this.sessionId, - seq: this.seq - }; - } - _handleGatewayMessage(ws, message) { try { message = JSON.parse(message); } catch(e) { - console.error("error: DiscordClient: on `message`: failed to parse incoming message as JSON", e); + console.error("error: DiscordClient: on 'message': failed to parse incoming message as JSON", e); return; } @@ -103,28 +94,20 @@ class DiscordClient extends EventEmitter { switch (message.op) { case opcodes.HELLO: { + console.log(`DiscordClient: HELLO; heartbeat_interval=${payload.heartbeat_interval}`); this._setHeartbeat(payload.heartbeat_interval); - if (this.resuming) { - console.warn("DiscordClient: resuming..."); - this.resuming = false; - ws.send(JSON.stringify({ - op: opcodes.RESUME, - d: this._getResumePayload() - })); - } else { - ws.send(JSON.stringify({ - op: opcodes.IDENTIFY, - d: this._getIdentifyPayload() - })); - } + ws.send(JSON.stringify({ + op: opcodes.IDENTIFY, + d: this._getIdentifyPayload() + })); break; } case opcodes.EVENT: { switch (message.t) { case "READY": { - console.log("DiscordClient: ready"); + console.log("DiscordClient: READY"); this.user = payload.user; this.sessionId = payload.session_id; this.guilds = payload.guilds; @@ -211,19 +194,8 @@ class DiscordClient extends EventEmitter { } case opcodes.INVALID_SESSION: { - if (message.d) { - // connection is resumable, we are going to resume the connection - this.resuming = true; - this.connect(); - } else { - // connection is not resumable, wait some time and then send a new IDENTIFY payload - setTimeout(() => { - ws.send(JSON.stringify({ - op: opcodes.IDENTIFY, - d: this._getIdentifyPayload() - })); - }, 3500); - } + console.error("DiscordClient: INVALID_SESSION - please check your authentication token"); + console.error("DiscordClient: INVALID_SESSION: will not reconnect"); break; } @@ -235,7 +207,9 @@ class DiscordClient extends EventEmitter { } connect() { + console.log("DiscordClient: connecting..."); if (this.ws) { + console.log("DiscordClient: a websocket connection already exists, killing..."); this.ws.removeAllListeners(); this.ws.close(); this.ws = null; @@ -249,30 +223,37 @@ class DiscordClient extends EventEmitter { }); // we decompressed the data, send it to the handler now - this.inflate.on("data", (message) => this._handleGatewayMessage(ws, message)); - + this.inflate.on("data", (message) => + this._handleGatewayMessage(ws, message) + ); ws.on("message", (data, isBinary) => { // pass the data to the decompressor this.inflate.write(data); }); + + ws.on("open", () => { + console.log("DiscordClient: WebSocket 'open'") + }); + ws.on("close", (code, reason) => { reason = reason.toString(); - console.error(`DiscordClient: on \`close\`: disconnected from gateway: code \`${code}\`, reason \`${reason}\``); + console.error(`DiscordClient: on 'close': disconnected from gateway: code '${code}', reason '${reason}'`); this.emit("close", code, reason); this._setHeartbeat(-1); - if (reconnectOnCloseCodes.includes(code)) { - this.resuming = true; + if (skipReconnectFor.includes(code)) { + console.error("DiscordClient: on 'close': the exit code above is in skipReconnectFor, and thus the server will not reconnect."); + } else { + console.log("DiscordClient: on 'close': the client will now attempt to reconnect..."); this.connect(); } }); ws.on("error", (e) => { - console.error("DiscordClient: websocket error:", e); - console.log("DiscordClient: reconnecting?"); + console.error("DiscordClient: on 'error': websocket error:", e); + console.log("DiscordClient: on 'error': reconnecting due to previous websocket error..."); this._setHeartbeat(-1); - this.resuming = true; this.connect(); }); } @@ -301,4 +282,4 @@ class DiscordClient extends EventEmitter { } } -export default DiscordClient; \ No newline at end of file +export default DiscordClient;