Rewrite WebSocket internals (#1410)

* Start rewriting Manager and Connection

* more stuff

* stuff

* Fix ready bug

* some stuff i forgot

* fix some stuff

* add stupid heartbeat ack like seriously who cares

* woo!

* fix a bug

* rate limit the dumb websocket

* stuff

* hdocs

* Docs

* Remove ClientManager#setupKeepAlive as it is now redundant

* Change Client._pingTimestamp to a getter that fetches the timestamp from the WebSocketConnection

* are you happy now eslint smh

* make gus happy

* Add CloseEvent external doc

* Make sure to emit 'reconnecting' when actually reconnecting

* ffs

* Fix RESUME logic

* Add heartbeat ack debug messages, including latency data

* Dumb stuff for Gus

* thx eslint

* more dumb stuff

* more dumb crap smh gus i h8 u

* moar messages

* fix for using wrong status, causing certain events not to be fired (#1422)
This commit is contained in:
Amish Shah
2017-04-28 16:13:06 +01:00
committed by GitHub
parent 95bcac9d9b
commit 195fcfa15c
13 changed files with 541 additions and 432 deletions

View File

@@ -2,6 +2,7 @@ const Constants = require('../../../util/Constants');
const BeforeReadyWhitelist = [
Constants.WSEvents.READY,
Constants.WSEvents.RESUMED,
Constants.WSEvents.GUILD_CREATE,
Constants.WSEvents.GUILD_DELETE,
Constants.WSEvents.GUILD_MEMBERS_CHUNK,
@@ -10,8 +11,8 @@ const BeforeReadyWhitelist = [
];
class WebSocketPacketManager {
constructor(websocketManager) {
this.ws = websocketManager;
constructor(connection) {
this.ws = connection;
this.handlers = {};
this.queue = [];
@@ -63,35 +64,12 @@ class WebSocketPacketManager {
handleQueue() {
this.queue.forEach((element, index) => {
this.handle(this.queue[index]);
this.handle(this.queue[index], true);
this.queue.splice(index, 1);
});
}
setSequence(s) {
if (s && s > this.ws.sequence) this.ws.sequence = s;
}
handle(packet) {
if (packet.op === Constants.OPCodes.RECONNECT) {
this.setSequence(packet.s);
this.ws.tryReconnect();
return false;
}
if (packet.op === Constants.OPCodes.INVALID_SESSION) {
this.client.emit('debug', `SESSION INVALID! Waiting to reconnect: ${packet.d}`);
if (packet.d) {
setTimeout(() => {
this.ws._sendResume();
}, 2500);
} else {
this.ws.sessionID = null;
this.ws._sendNewIdentify();
}
return false;
}
handle(packet, queue = false) {
if (packet.op === Constants.OPCodes.HEARTBEAT_ACK) {
this.ws.client._pong(this.ws.client._pingTimestamp);
this.ws.lastHeartbeatAck = true;
@@ -109,7 +87,7 @@ class WebSocketPacketManager {
this.ws.checkIfReady();
}
this.setSequence(packet.s);
this.ws.setSequence(packet.s);
if (this.ws.disabledEvents[packet.t] !== undefined) return false;
@@ -120,6 +98,8 @@ class WebSocketPacketManager {
}
}
if (!queue && this.queue.length > 0) this.handleQueue();
if (this.handlers[packet.t]) return this.handlers[packet.t].handle(packet);
return false;
}

View File

@@ -59,10 +59,12 @@ class ReadyHandler extends AbstractHandler {
});
}
client.setTimeout(() => {
if (!client.ws.normalReady) client.ws._emitReady(false);
const t = client.setTimeout(() => {
client.ws.connection.triggerReady();
}, 1200 * data.guilds.length);
client.once('ready', () => client.clearTimeout(t));
const ws = this.packetManager.ws;
ws.sessionID = data.session_id;

View File

@@ -1,18 +1,20 @@
const AbstractHandler = require('./AbstractHandler');
const Constants = require('../../../../util/Constants');
class ResumedHandler extends AbstractHandler {
handle(packet) {
const client = this.packetManager.client;
const ws = client.ws;
const ws = client.ws.connection;
ws._trace = packet.d._trace;
const replayed = ws.sequence - ws.resumeStart;
ws.resumeStart = -1;
ws.status = Constants.Status.READY;
this.packetManager.handleQueue();
const replayed = ws.sequence - ws.closeSequence;
client.emit('debug', `RESUMED ${ws._trace.join(' -> ')} | replayed ${replayed} events. `);
client.emit('resume', replayed);
ws.heartbeat();
}
}