From 458106466645750002aa0a44bfebc43c70364cd9 Mon Sep 17 00:00:00 2001 From: Ahmed Alaa Date: Tue, 28 Jul 2015 22:12:07 +0300 Subject: [PATCH 1/2] add keepAlive in setTimeout function --- index.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 97a77fc..2ffed51 100644 --- a/index.js +++ b/index.js @@ -20,7 +20,9 @@ function TeamSpeakClient(host, port){ reader = null, status = -2, queue = [], - executing = null; + executing = null + keeper, + lastData; function tsescape(s){ var r = String(s); @@ -134,12 +136,26 @@ function TeamSpeakClient(host, port){ }; // SetTimeout function - TeamSpeakClient.prototype.setTimeout = function(time) { - socket.setTimeout(time || 60000, function() { - socket.destroy(); - self.emit("timeout"); - }); - }; + TeamSpeakClient.prototype.setTimeout = function(keepAlive, time) { + time = time || 10000; + socket.setTimeout(time, function() { + socket.destroy(); + self.emit("timeout"); + }); + if (keepAlive) { + // Clear old keeper intervals if available + if (keeper) clearInterval(keeper); + // Set the keeper interval to fireup 1 sec before the timeout + keeper = setInterval(function() { + if (new Date().getTime() - lastData > (time - 1000)) { + self.send("version", function(err, response, rawResponse) { + if (!err) self.emit("keepAlive"); + }); + } + }, 500); + } + }; + socket.on("error", function(err){ self.emit("error", err); @@ -149,6 +165,12 @@ function TeamSpeakClient(host, port){ self.emit("close", queue); }); + // Register the on data event to update the lastData timestamp for the keepAlive + socket.on("data", function(data) { + lastData = new Date().getTime(); + self.emit("data", data); + }); + socket.on("connect", function(){ reader = LineInputStream(socket); reader.on("line", function(line){ From 420c07932911e22cee2b8be712e90e10856123ed Mon Sep 17 00:00:00 2001 From: Ahmed90 Date: Thu, 10 Dec 2015 22:58:10 +0200 Subject: [PATCH 2/2] fixing keeper/ syntax error --- index.js | 363 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 185 insertions(+), 178 deletions(-) diff --git a/index.js b/index.js index 2ffed51..adcfabb 100644 --- a/index.js +++ b/index.js @@ -7,135 +7,142 @@ * ---------------------------------------------------------------------------- */ -var net = require("net"), - LineInputStream = require("line-input-stream"), - events = require("events"), - util = require("util"); - -function TeamSpeakClient(host, port){ - events.EventEmitter.call(this); - - var self = this, - socket = net.connect(port || 10011, host || 'localhost'), - reader = null, - status = -2, - queue = [], - executing = null - keeper, - lastData; - - function tsescape(s){ - var r = String(s); - r = r.replace(/\\/g, "\\\\"); // Backslash - r = r.replace(/\//g, "\\/"); // Slash - r = r.replace(/\|/g, "\\p"); // Pipe - r = r.replace(/\n/g, "\\n"); // Newline - r = r.replace(/\r/g, "\\r"); // Carriage Return - r = r.replace(/\t/g, "\\t"); // Tab - r = r.replace(/\v/g, "\\v"); // Vertical Tab - r = r.replace(/\f/g, "\\f"); // Formfeed - r = r.replace(/ /g, "\\s"); // Whitespace - return r; - } - - function tsunescape(s){ - var r = String(s); - r = r.replace(/\\s/g, " "); // Whitespace - r = r.replace(/\\p/g, "|"); // Pipe - r = r.replace(/\\n/g, "\n"); // Newline - r = r.replace(/\\f/g, "\f"); // Formfeed - r = r.replace(/\\r/g, "\r"); // Carriage Return - r = r.replace(/\\t/g, "\t"); // Tab - r = r.replace(/\\v/g, "\v"); // Vertical Tab - r = r.replace(/\\\//g, "\/"); // Slash - r = r.replace(/\\\\/g, "\\"); // Backslash - return r; - } - - function checkQueue(){ - if(!executing && queue.length >= 1){ - executing = queue.shift(); - socket.write(executing.text + "\n"); - } - } - - function parseResponse(s){ - var response = []; - var records = s.split("|"); - - response = records.map(function(k){ - var args = k.split(" "); - var thisrec = {}; - args.forEach(function(v){ - if(v.indexOf("=") > -1){ - var key = tsunescape(v.substr(0, v.indexOf("="))); - var value = tsunescape(v.substr(v.indexOf("=")+1)); - if(parseInt(value, 10) == value) value = parseInt(value, 10); - thisrec[key] = value; - }else thisrec[v] = ""; - }); - return thisrec; - }); - - if(response.length === 0){ - response = null; - } else if(response.length === 1){ - response = response.shift(); - } - - return response; - } - - // Return pending commands that are going to be sent to the server. - // Note that they have been parsed - Access getPending()[0].text to get - // the full text representation of the command. - TeamSpeakClient.prototype.getPending = function(){ - return queue.slice(0); - }; - - // Clear the queue of pending commands so that any command that is currently queued won't be executed. - // The old queue is returned. - TeamSpeakClient.prototype.clearPending = function(){ - var q = queue; - queue = []; - return q; - }; - - // Send a command to the server - TeamSpeakClient.prototype.send = function(){ - var args = Array.prototype.slice.call(arguments); - var options = [], params = {}; - var callback = undefined; - var cmd = args.shift(); - args.forEach(function(v){ - if(util.isArray(v)){ - options = v; - } else if(typeof v === "function"){ - callback = v; - } else { - params = v; - } - }); - var tosend = tsescape(cmd); - options.forEach(function(v){ - tosend += " -" + tsescape(v); - }); - for(var k in params){ - var v = params[k]; - if(util.isArray(v)){ // Multiple values for the same key - concatenate all - var doptions = v.map(function(val){ - return tsescape(k) + "=" + tsescape(val); - }); - tosend += " " + doptions.join("|"); - } else { - tosend += " " + tsescape(k.toString()) + "=" + tsescape(v.toString()); - } - } - queue.push({cmd: cmd, options: options, parameters: params, text: tosend, cb: callback}); - if(status === 0) checkQueue(); - }; - - // SetTimeout function +var net = require("net"), + LineInputStream = require("line-input-stream"), + events = require("events"), + util = require("util"); + +function TeamSpeakClient(host, port) { + events.EventEmitter.call(this); + + var self = this, + socket = net.connect(port || 10011, host || 'localhost'), + reader = null, + status = -2, + queue = [], + executing = null, + keeper = null, + lastData = null; + + function tsescape(s) { + var r = String(s); + r = r.replace(/\\/g, "\\\\"); // Backslash + r = r.replace(/\//g, "\\/"); // Slash + r = r.replace(/\|/g, "\\p"); // Pipe + r = r.replace(/\n/g, "\\n"); // Newline + r = r.replace(/\r/g, "\\r"); // Carriage Return + r = r.replace(/\t/g, "\\t"); // Tab + r = r.replace(/\v/g, "\\v"); // Vertical Tab + r = r.replace(/\f/g, "\\f"); // Formfeed + r = r.replace(/ /g, "\\s"); // Whitespace + return r; + } + + function tsunescape(s) { + var r = String(s); + r = r.replace(/\\s/g, " "); // Whitespace + r = r.replace(/\\p/g, "|"); // Pipe + r = r.replace(/\\n/g, "\n"); // Newline + r = r.replace(/\\f/g, "\f"); // Formfeed + r = r.replace(/\\r/g, "\r"); // Carriage Return + r = r.replace(/\\t/g, "\t"); // Tab + r = r.replace(/\\v/g, "\v"); // Vertical Tab + r = r.replace(/\\\//g, "\/"); // Slash + r = r.replace(/\\\\/g, "\\"); // Backslash + return r; + } + + function checkQueue() { + if (!executing && queue.length >= 1) { + executing = queue.shift(); + socket.write(executing.text + "\n"); + } + } + + function parseResponse(s) { + var response = []; + var records = s.split("|"); + + response = records.map(function(k) { + var args = k.split(" "); + var thisrec = {}; + args.forEach(function(v) { + if (v.indexOf("=") > -1) { + var key = tsunescape(v.substr(0, v.indexOf("="))); + var value = tsunescape(v.substr(v.indexOf("=") + 1)); + if (parseInt(value, 10) == value) value = parseInt(value, 10); + thisrec[key] = value; + } else thisrec[v] = ""; + }); + return thisrec; + }); + + if (response.length === 0) { + response = null; + } else if (response.length === 1) { + response = response.shift(); + } + + return response; + } + + // Return pending commands that are going to be sent to the server. + // Note that they have been parsed - Access getPending()[0].text to get + // the full text representation of the command. + TeamSpeakClient.prototype.getPending = function() { + return queue.slice(0); + }; + + // Clear the queue of pending commands so that any command that is currently queued won't be executed. + // The old queue is returned. + TeamSpeakClient.prototype.clearPending = function() { + var q = queue; + queue = []; + return q; + }; + + // Send a command to the server + TeamSpeakClient.prototype.send = function() { + var args = Array.prototype.slice.call(arguments); + var options = [], + params = {}; + var callback = undefined; + var cmd = args.shift(); + args.forEach(function(v) { + if (util.isArray(v)) { + options = v; + } else if (typeof v === "function") { + callback = v; + } else { + params = v; + } + }); + var tosend = tsescape(cmd); + options.forEach(function(v) { + tosend += " -" + tsescape(v); + }); + for (var k in params) { + var v = params[k]; + if (util.isArray(v)) { // Multiple values for the same key - concatenate all + var doptions = v.map(function(val) { + return tsescape(k) + "=" + tsescape(val); + }); + tosend += " " + doptions.join("|"); + } else { + tosend += " " + tsescape(k.toString()) + "=" + tsescape(v.toString()); + } + } + queue.push({ + cmd: cmd, + options: options, + parameters: params, + text: tosend, + cb: callback + }); + if (status === 0) checkQueue(); + }; + + // SetTimeout function TeamSpeakClient.prototype.setTimeout = function(keepAlive, time) { time = time || 10000; socket.setTimeout(time, function() { @@ -156,55 +163,55 @@ function TeamSpeakClient(host, port){ } }; - - socket.on("error", function(err){ - self.emit("error", err); - }); - - socket.on("close", function(){ - self.emit("close", queue); - }); - - // Register the on data event to update the lastData timestamp for the keepAlive - socket.on("data", function(data) { - lastData = new Date().getTime(); - self.emit("data", data); - }); - - socket.on("connect", function(){ - reader = LineInputStream(socket); - reader.on("line", function(line){ - var s = line.trim(); - // Ignore two first lines sent by server ("TS3" and information message) - if(status < 0){ - status++; - if(status === 0) checkQueue(); - return; - } - // Server answers with: - // [- One line containing the answer ] - // - "error id=XX msg=YY". ID is zero if command was executed successfully. - var response = undefined; - if(s.indexOf("error") === 0){ - response = parseResponse(s.substr("error ".length).trim()); - executing.error = response; - if(executing.error.id === 0) delete executing.error; - if(executing.cb) executing.cb.call(executing, executing.error, executing.response, - executing.rawResponse); - executing = null; - checkQueue(); - } else if(s.indexOf("notify") === 0){ - s = s.substr("notify".length); - response = parseResponse(s); - self.emit(s.substr(0, s.indexOf(" ")), response); - } else if(executing) { - response = parseResponse(s); - executing.rawResponse = s; - executing.response = response; - } - }); - self.emit("connect"); - }); + + socket.on("error", function(err) { + self.emit("error", err); + }); + + socket.on("close", function() { + self.emit("close", queue); + }); + + // Register the on data event to update the lastData timestamp for the keepAlive + socket.on("data", function(data) { + lastData = new Date().getTime(); + self.emit("data", data); + }); + + socket.on("connect", function() { + reader = LineInputStream(socket); + reader.on("line", function(line) { + var s = line.trim(); + // Ignore two first lines sent by server ("TS3" and information message) + if (status < 0) { + status++; + if (status === 0) checkQueue(); + return; + } + // Server answers with: + // [- One line containing the answer ] + // - "error id=XX msg=YY". ID is zero if command was executed successfully. + var response = undefined; + if (s.indexOf("error") === 0) { + response = parseResponse(s.substr("error ".length).trim()); + executing.error = response; + if (executing.error.id === 0) delete executing.error; + if (executing.cb) executing.cb.call(executing, executing.error, executing.response, + executing.rawResponse); + executing = null; + checkQueue(); + } else if (s.indexOf("notify") === 0) { + s = s.substr("notify".length); + response = parseResponse(s); + self.emit(s.substr(0, s.indexOf(" ")), response); + } else if (executing) { + response = parseResponse(s); + executing.rawResponse = s; + executing.response = response; + } + }); + self.emit("connect"); + }); } util.inherits(TeamSpeakClient, events.EventEmitter);