src: Cleanup event listeners on WebSocket connections (#3681)

* src: Cleanup event listeners on WebSocket connections
Should prevent #3641 from happening, as well as double connections on a shard

* typings: Forgot to add the method
This commit is contained in:
Vlad Frangu
2020-01-13 20:53:07 +02:00
committed by Amish Shah
parent 45cd58b68c
commit c23cc7a42e
3 changed files with 29 additions and 5 deletions

View File

@@ -245,6 +245,8 @@ class WebSocketManager extends EventEmitter {
});
shard.on(ShardEvents.DESTROYED, () => {
shard._cleanupConnection();
this.debug('Shard was destroyed but no WebSocket connection was present! Reconnecting...', shard);
this.client.emit(Events.SHARD_RECONNECTING, shard.id);

View File

@@ -208,11 +208,18 @@ class WebSocketShard extends EventEmitter {
this.once(ShardEvents.INVALID_SESSION, onInvalid);
if (this.connection && this.connection.readyState === WebSocket.OPEN) {
this.debug('Connection found, attempting an immediate identify.');
this.debug('An open connection was found, attempting an immediate identify.');
this.identify();
return;
}
if (this.connection) {
this.debug(`A connection was found. Cleaning up before continuing.
State: ${CONNECTION_STATE[this.connection.readyState]}`);
this._cleanupConnection();
this.connection.close(1000);
}
const wsQuery = { v: client.options.ws.version };
if (zlib) {
@@ -526,9 +533,9 @@ class WebSocketShard extends EventEmitter {
} else if (!this.lastHeartbeatAcked) {
this.debug(
`[${tag}] Didn't receive a heartbeat ack last time, assuming zombie connection. Destroying and reconnecting.
Status : ${STATUS_KEYS[this.status]}
Sequence : ${this.sequence}
Connection State: ${this.connection ? CONNECTION_STATE[this.connection.readyState] : 'No Connection??'}`
Status : ${STATUS_KEYS[this.status]}
Sequence : ${this.sequence}
Connection State: ${this.connection ? CONNECTION_STATE[this.connection.readyState] : 'No Connection??'}`
);
this.destroy(4009);
return;
@@ -629,7 +636,8 @@ class WebSocketShard extends EventEmitter {
*/
_send(data) {
if (!this.connection || this.connection.readyState !== WebSocket.OPEN) {
this.debug(`Tried to send packet ${JSON.stringify(data)} but no WebSocket is available!`);
this.debug(`Tried to send packet ${JSON.stringify(data)} but no WebSocket is available! Resetting the shard...`);
this.destroy(4000);
return;
}
@@ -667,6 +675,8 @@ class WebSocketShard extends EventEmitter {
* @private
*/
destroy(closeCode = 1000, cleanup = false) {
this.debug(`Destroying with close code ${closeCode}, attempting a reconnect: ${!cleanup}`);
this.setHeartbeatTimer(-1);
this.setHelloTimeout(-1);
@@ -696,6 +706,17 @@ class WebSocketShard extends EventEmitter {
this.ratelimit.timer = null;
}
}
/**
* Cleans up the WebSocket connection listeners.
* @private
*/
_cleanupConnection() {
this.connection.onopen =
this.connection.onclose =
this.connection.onerror =
this.connection.onmessage = null;
}
}
module.exports = WebSocketShard;

1
typings/index.d.ts vendored
View File

@@ -1717,6 +1717,7 @@ declare module 'discord.js' {
private _send(data: object): void;
private processQueue(): void;
private destroy(closeCode: number): void;
private _cleanupConnection(): void;
public send(data: object): void;
public on(event: 'ready', listener: () => void): this;