Add etf encoding support with erlpack (#943)

* the performance from this is astounding

* help uws

* save 15 bytes in webpacks

* update readme

* why is markdown like this

* optimizations

* Update WebSocketManager.js
This commit is contained in:
Gus Caplan
2016-12-02 20:35:59 -06:00
committed by Schuyler Cebulskie
parent 58c7c2e7b8
commit 1e5afc1608
4 changed files with 26 additions and 7 deletions

View File

@@ -27,7 +27,8 @@ Usability and performance are key focuses of discord.js, and it also has nearly
Without voice support: `npm install discord.js --save`
With voice support ([node-opus](https://www.npmjs.com/package/node-opus)): `npm install discord.js node-opus --save`
With voice support ([opusscript](https://www.npmjs.com/package/opusscript)): `npm install discord.js opusscript --save`
With fast websockets ([uws](https://www.npmjs.com/package/uws)) `npm install discord.js uws --save`
With a fast websocket client ([uws](https://www.npmjs.com/package/uws)) `npm install discord.js uws --save`
With fast websocket encoding ([erlpack](https://github.com/hammerandchisel/erlpack)) `npm install disscord.js hammerandchisel/erlpack --save`
The preferred audio engine is node-opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose node-opus.
Using opusscript is only recommended for development environments where node-opus is tough to get working.

View File

@@ -37,6 +37,7 @@
"ws": "^1.1.1"
},
"peerDependencies": {
"erlpack": "github:hammerandchisel/erlpack",
"node-opus": "^0.2.0",
"opusscript": "^0.0.1",
"uws": "^0.11.1"
@@ -58,6 +59,7 @@
"browser": {
"ws": false,
"uws": false,
"erlpack": false,
"opusscript": false,
"node-opus": false,
"tweet-nacl": false,

View File

@@ -38,7 +38,7 @@ class RESTMethods {
getGateway() {
return this.rest.makeRequest('get', Constants.Endpoints.gateway, true).then(res => {
this.rest.client.ws.gateway = `${res.url}/?encoding=json&v=${Constants.PROTOCOL_VERSION}`;
this.rest.client.ws.gateway = `${res.url}/?v=${Constants.PROTOCOL_VERSION}`;
return this.rest.client.ws.gateway;
});
}

View File

@@ -1,6 +1,7 @@
const browser = typeof window !== 'undefined';
const EventEmitter = require('events').EventEmitter;
const Constants = require('../../util/Constants');
const convertArrayBuffer = require('../../util/ConvertArrayBuffer');
const pako = require('pako');
const zlib = require('zlib');
const PacketManager = require('./packets/WebSocketPacketManager');
@@ -16,6 +17,15 @@ if (browser) {
}
}
let erlpack, serialize;
try {
erlpack = require('erlpack');
serialize = erlpack.pack;
} catch (err) {
erlpack = null;
serialize = JSON.stringify;
}
/**
* The WebSocket Manager of the Client
* @private
@@ -100,6 +110,7 @@ class WebSocketManager extends EventEmitter {
}
connect(gateway) {
gateway = `${gateway}&encoding=${erlpack ? 'etf' : 'json'}`;
if (this.first) {
this._connect(gateway);
this.first = false;
@@ -115,10 +126,10 @@ class WebSocketManager extends EventEmitter {
*/
send(data, force = false) {
if (force) {
this._send(JSON.stringify(data));
this._send(serialize(data));
return;
}
this._queue.push(JSON.stringify(data));
this._queue.push(serialize(data));
this.doQueue();
}
@@ -240,9 +251,14 @@ class WebSocketManager extends EventEmitter {
* @returns {Object}
*/
parseEventData(data) {
if (data instanceof ArrayBuffer) data = pako.inflate(data, { to: 'string' });
else if (data instanceof Buffer) data = zlib.inflateSync(data).toString();
return JSON.parse(data);
if (erlpack) {
if (data instanceof ArrayBuffer) data = convertArrayBuffer(data);
return erlpack.unpack(data);
} else {
if (data instanceof ArrayBuffer) data = pako.inflate(data, { to: 'string' });
else if (data instanceof Buffer) data = zlib.inflateSync(data).toString();
return JSON.parse(data);
}
}
/**