Skip to content

Commit

Permalink
Fixed version
Browse files Browse the repository at this point in the history
  • Loading branch information
dufourgilles committed May 25, 2019
2 parents 1f3cf0f + 0e34ada commit cc6a04e
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 63 deletions.
48 changes: 28 additions & 20 deletions client.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,28 @@ 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,
timeout: timeout
timeout: 1000 * timeout
},
() => {
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);
Expand All @@ -201,23 +210,22 @@ S101Socket.prototype.connect = function (timeout = 2) {
});

self.emit('connected');
}
).on('error', (e) => {
self.emit("error", e);
});

self.socket.on('data', (data) => {
if (self.isConnected()) {
self.codec.dataIn(data);
}
});

self.socket.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 () {
Expand Down
40 changes: 26 additions & 14 deletions device.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ DeviceTree.prototype.getDirectory = function (qnode) {
}

self.callback = (error, node) => {
if (node == null) { return; }
if (node == null) { return; }
if (error) {
if (self._debug) {
console.log("Received getDirectory error", error);
Expand All @@ -160,25 +160,37 @@ DeviceTree.prototype.getDirectory = function (qnode) {
reject(error);
return;
}
let requestedPath = qnode.getPath();
if (requestedPath === "") {
if (qnode instanceof ember.Root) {
if (qnode.elements == null || qnode.elements.length === 0) {
if (self._debug) {
console.log("getDirectory response", node);
console.log("getDirectory response", node);
}
return self.callback(new Error("Invalid qnode for getDirectory"));
}
requestedPath = qnode.elements["0"].getPath();
}
const nodeElements = node == null ? null : node.elements;
if (nodeElements != null
&& nodeElements.every(el => el.getPath() === requestedPath || isDirectSubPathOf(el.getPath(), requestedPath))) {
if (self._debug) {
console.log("Received getDirectory response", node);

const nodeElements = node == null ? null : node.elements;

if (nodeElements != null
&& nodeElements.every(el => el._parent instanceof ember.Root)) {
if (self._debug) {
console.log("Received getDirectory response", node);
}
self.clearTimeout(); // clear the timeout now. The resolve below may take a while.
self.finishRequest();
resolve(node); // make sure the info is treated before going to next request.
}
} else {
let requestedPath = qnode.getPath();
const nodeElements = node == null ? null : node.elements;
if (nodeElements != null
&& nodeElements.every(el => isDirectSubPathOf(el.getPath(), requestedPath))) {
if (self._debug) {
console.log("Received getDirectory response", node);
}
self.clearTimeout(); // clear the timeout now. The resolve below may take a while.
self.finishRequest();
resolve(node); // make sure the info is treated before going to next request.
}
self.clearTimeout(); // clear the timeout now. The resolve below may take a while.
self.finishRequest();
resolve(node); // make sure the info is treated before going to next request.
}
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "emberplus",
"version": "1.7.20",
"version": "1.7.22",
"description": "Javascript implementation of the Ember+ automation protocol",
"main": "index.js",
"scripts": {
Expand Down
92 changes: 64 additions & 28 deletions test/DeviceTree.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,76 @@ const DeviceTree = require("../").DeviceTree;
const TreeServer = require("../").TreeServer;

const LOCALHOST = "127.0.0.1";
const UNKNOWN_HOST = "192.168.99.99";
const PORT = 9008;

describe("DeviceTree", () => {
let server;

beforeAll(() => {
return Promise.resolve()
.then(() => new Promise((resolve, reject) => {
fs.readFile("./embrionix.ember", (e, data) => {
if (e) {
reject(e);
}
resolve(Decoder(data));
describe("With server", () => {
let server;
beforeAll(() => {
return Promise.resolve()
.then(() => new Promise((resolve, reject) => {
fs.readFile("./embrionix.ember", (e, data) => {
if (e) {
reject(e);
}
resolve(Decoder(data));
});
}))
.then(root => {
server = new TreeServer(LOCALHOST, PORT, root);
return server.listen();
});
}))
.then(root => {
server = new TreeServer(LOCALHOST, PORT, root);
return server.listen();
});
});
});

afterAll(() => server.close());

it("should gracefully connect and disconnect", () => {
return Promise.resolve()
.then(() => {
let tree = new DeviceTree(LOCALHOST, PORT);
return Promise.resolve()
.then(() => tree.connect())
.then(() => tree.getDirectory())
.then(() => tree.disconnect())
.then(() => tree.connect())
.then(() => tree.getDirectory())
.then(() => tree.disconnect())
})
});

it("should not disconnect after 5 seconds of inactivity", () => {
return Promise.resolve()
.then(() => {
let tree = new DeviceTree(LOCALHOST, PORT);

afterAll(() => server.close());
tree.on("error", error => {
throw error;
});

it("should gracefully connect and disconnect", () => {
return Promise.resolve()
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", () => {
let tree = new DeviceTree(UNKNOWN_HOST, PORT);
tree.on("error", () => {
});
const expectedTimeoutInSec = 2;
const initialTime = performance.now();
return tree.connect(expectedTimeoutInSec)
.then(() => {
let tree = new DeviceTree(LOCALHOST, PORT);
return Promise.resolve()
.then(() => tree.connect())
.then(() => tree.getDirectory())
.then(() => tree.disconnect())
.then(() => tree.connect())
.then(() => tree.getDirectory())
.then(() => tree.disconnect())
})
throw new Error("Should have thrown");
},
error => {
const durationMs = performance.now() - initialTime;
const deltaMs = Math.abs(expectedTimeoutInSec * 1000 - durationMs);
expect(deltaMs).toBeLessThan(10);
expect(error.message).toBe(`Could not connect to ${UNKNOWN_HOST}:${PORT} after a timeout of ${expectedTimeoutInSec} seconds`)
});
});
});

0 comments on commit cc6a04e

Please sign in to comment.