diff --git a/client.js b/client.js index cba85d5..a60916a 100755 --- a/client.js +++ b/client.js @@ -165,6 +165,12 @@ S101Socket.prototype.connect = function (timeout = 2) { self.emit('connecting'); self.codec = new S101Codec(); + + const connectTimeoutListener = () => { + self.socket.destroy(); + self.emit("error", new Error(`Could not connect to ${self.address}:${self.port} after a timeout of ${timeout} seconds`)); + }; + self.socket = net.createConnection({ port: self.port, host: self.address, @@ -173,11 +179,14 @@ S101Socket.prototype.connect = function (timeout = 2) { () => { winston.debug('socket connected'); + // Disable connect timeout to hand-over to keepalive mechanism + self.socket.removeListener("timeout", connectTimeoutListener); + self.socket.setTimeout(0); + self.keepaliveIntervalTimer = setInterval(() => { try { self.sendKeepaliveRequest(); - } - catch(e) { + } catch (e) { self.emit("error", e); } }, 1000 * self.keepaliveInterval); @@ -201,22 +210,22 @@ S101Socket.prototype.connect = function (timeout = 2) { }); self.emit('connected'); - } - ).on('error', (e) => { - self.emit("error", e); - }).on("timeout", () => { - self.socket.destroy(); - self.emit("error", new Error(`Could not connect to ${self.address}:${self.port} after a timeout of ${timeout} seconds`)); - }).on('data', (data) => { - if (self.isConnected()) { - self.codec.dataIn(data); - } - }).on('close', () => { - clearInterval(self.keepaliveIntervalTimer); - self.emit('disconnected'); - self.status = "disconnected"; - self.socket = null; - }); + }) + .on('error', (e) => { + self.emit("error", e); + }) + .once("timeout", connectTimeoutListener) + .on('data', (data) => { + if (self.isConnected()) { + self.codec.dataIn(data); + } + }) + .on('close', () => { + clearInterval(self.keepaliveIntervalTimer); + self.emit('disconnected'); + self.status = "disconnected"; + self.socket = null; + }); } S101Socket.prototype.isConnected = function () { diff --git a/test/DeviceTree.test.js b/test/DeviceTree.test.js index c0a7c73..0c82675 100644 --- a/test/DeviceTree.test.js +++ b/test/DeviceTree.test.js @@ -41,6 +41,22 @@ describe("DeviceTree", () => { .then(() => tree.disconnect()) }) }); + + it("should not disconnect after 5 seconds of inactivity", () => { + return Promise.resolve() + .then(() => { + let tree = new DeviceTree(LOCALHOST, PORT); + + tree.on("error", error => { + throw error; + }); + + return Promise.resolve() + .then(() => tree.connect()) + .then(() => new Promise(resolve => setTimeout(resolve, 5000))) + .then(() => tree.disconnect()) + }) + }, 7000); }); it("timeout should be taken into account when connecting to unknown host", () => {