diff --git a/README.md b/README.md index 5e386dd..576204c 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,22 @@ function(e,state) { > npm install sonicsnes/node-gamedig > ``` -### Input Parameters +### Query Options + +**Typical** * **type**: One of the game IDs listed in the game list below -* **host** +* **host**: Hostname or IP of the game server * **port**: (optional) Uses the protocol default if not set -* **notes**: (optional) Passed through to output -* **maxAttempts**: (optional) Number of attempts to query server in case of failure (default 1) + +**Advanced** + +* **notes**: (optional) An object passed through in the return value. +* **maxAttempts**: (optional) Number of attempts to query server in case of failure. (default 1) +* **socketTimeout**: (optional) Milliseconds to wait for a single packet. Beware that increasing this + will cause many queries to take longer even if the server is online. (default 1000) +* **attemptTimeout**: (optional) Milliseconds allowed for an entire query attempt. This timeout is not commonly hit, + as the socketTimeout typically fires first. (default 10000) ### Return Value diff --git a/protocols/core.js b/protocols/core.js index 348b266..06e16fc 100644 --- a/protocols/core.js +++ b/protocols/core.js @@ -9,8 +9,8 @@ class Core extends EventEmitter { constructor() { super(); this.options = { - tcpTimeout: 1000, - udpTimeout: 1000, + socketTimeout: 1000, + attemptTimeout: 10000, maxAttempts: 1 }; this.attempt = 1; @@ -19,10 +19,7 @@ class Core extends EventEmitter { this.byteorder = 'le'; this.delimiter = '\0'; this.srvRecord = null; - - this.globalTimeoutTimer = setTimeout(() => { - this.fatal('timeout'); - },10000); + this.attemptTimeoutTimer = null; } fatal(err,noretry) { @@ -58,7 +55,6 @@ class Core extends EventEmitter { done(state) { if(this.finished) return; - clearTimeout(this.globalTimeoutTimer); if(this.options.notes) state.notes = this.options.notes; @@ -71,6 +67,7 @@ class Core extends EventEmitter { state.query.type = this.type; if('pretty' in this) state.query.pretty = this.pretty; state.query.duration = Date.now() - this.startMillis; + state.query.attempts = this.attempt; this.reset(); this.finished = true; @@ -79,6 +76,7 @@ class Core extends EventEmitter { } reset() { + clearTimeout(this.attemptTimeoutTimer); if(this.timers) { for (const timer of this.timers) { clearTimeout(timer); @@ -101,6 +99,10 @@ class Core extends EventEmitter { this.startMillis = Date.now(); + this.attemptTimeoutTimer = setTimeout(() => { + this.fatal('timeout'); + },this.options.attemptTimeout); + async.series([ (c) => { // resolve host names @@ -211,7 +213,6 @@ class Core extends EventEmitter { connected = true; c(socket); }); - socket.setTimeout(10000); socket.setNoDelay(true); if(this.debug) console.log(address+':'+port+" TCPCONNECT"); @@ -255,13 +256,11 @@ class Core extends EventEmitter { this.tcpTimeoutTimer = this.setTimeout(() => { this.tcpCallback = false; this.fatal('TCP Watchdog Timeout'); - },this.options.tcpTimeout); + },this.options.socketTimeout); this.tcpCallback = ondata; }); } - - udpSend(buffer,onpacket,ontimeout) { process.nextTick(() => { if(this.udpCallback) return this.fatal('Attempted to send UDP packet while still waiting on a managed response'); @@ -273,7 +272,7 @@ class Core extends EventEmitter { let timeout = false; if(!ontimeout || ontimeout() !== true) timeout = true; if(timeout) this.fatal('UDP Watchdog Timeout'); - },this.options.udpTimeout); + },this.options.socketTimeout); this.udpCallback = onpacket; }); } diff --git a/protocols/mumble.js b/protocols/mumble.js index 5c11ba3..c0a9793 100644 --- a/protocols/mumble.js +++ b/protocols/mumble.js @@ -1,7 +1,7 @@ class Mumble extends require('./core') { constructor() { super(); - this.options.tcpTimeout = 5000; + this.options.socketTimeout = 5000; } run(state) {