discord.js/src/client/ClientManager.js
Amish Shah 195fcfa15c 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)
2017-04-28 16:13:06 +01:00

73 lines
2.3 KiB
JavaScript

const Constants = require('../util/Constants');
const WebSocketConnection = require('./websocket/WebSocketConnection');
/**
* Manages the State and Background Tasks of the Client
* @private
*/
class ClientManager {
constructor(client) {
/**
* The Client that instantiated this Manager
* @type {Client}
*/
this.client = client;
/**
* The heartbeat interval, null if not yet set
* @type {?number}
*/
this.heartbeatInterval = null;
}
/**
* The status of the client
* @type {number}
*/
get status() {
return this.connection ? this.connection.status : Constants.Status.IDLE;
}
/**
* Connects the Client to the WebSocket
* @param {string} token The authorization token
* @param {Function} resolve Function to run when connection is successful
* @param {Function} reject Function to run when connection fails
*/
connectToWebSocket(token, resolve, reject) {
this.client.emit(Constants.Events.DEBUG, `Authenticated using token ${token}`);
this.client.token = token;
const timeout = this.client.setTimeout(() => reject(new Error(Constants.Errors.TOOK_TOO_LONG)), 1000 * 300);
this.client.rest.methods.getGateway().then(res => {
const protocolVersion = Constants.DefaultOptions.ws.version;
const gateway = `${res.url}/?v=${protocolVersion}&encoding=${WebSocketConnection.ENCODING}`;
this.client.emit(Constants.Events.DEBUG, `Using gateway ${gateway}`);
this.client.ws.connect(gateway);
this.client.ws.once('close', event => {
if (event.code === 4004) reject(new Error(Constants.Errors.BAD_LOGIN));
if (event.code === 4010) reject(new Error(Constants.Errors.INVALID_SHARD));
if (event.code === 4011) reject(new Error(Constants.Errors.SHARDING_REQUIRED));
});
this.client.once(Constants.Events.READY, () => {
resolve(token);
this.client.clearTimeout(timeout);
});
}, reject);
}
destroy() {
this.client.ws.destroy();
this.client.rest.destroy();
if (!this.client.user) return Promise.resolve();
if (this.client.user.bot) {
this.client.token = null;
return Promise.resolve();
} else {
return this.client.rest.methods.logout().then(() => {
this.client.token = null;
});
}
}
}
module.exports = ClientManager;