Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add heartbeat tracker to websocket connection
Closes #488
- Loading branch information
Showing
12 changed files
with
216 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import Debug from 'debug'; | ||
|
||
import { Connection } from 'home-assistant-js-websocket'; | ||
|
||
const debug = Debug('home-assistant:ws:heartbeat'); | ||
|
||
export type StopHeartbeat = () => void; | ||
|
||
const HEARTBEAT_TIMEOUT = 5000; | ||
const MIN_HEARTBEAT_INTERVAL = 10000; | ||
|
||
export const startHeartbeat = ( | ||
client: Connection, | ||
interval: number, | ||
host: string | ||
): StopHeartbeat => { | ||
let heartbeatIntervalId: NodeJS.Timer; | ||
let beatTimeoutId: NodeJS.Timeout; | ||
|
||
heartbeatIntervalId = setInterval( | ||
async () => { | ||
beatTimeoutId = setTimeout(() => { | ||
debug(`No pong received from ${host} attempting to reconnect`); | ||
client.suspendReconnectUntil( | ||
new Promise((resolve) => { | ||
resolve(); | ||
}) | ||
); | ||
client.suspend(); | ||
}, HEARTBEAT_TIMEOUT); | ||
|
||
debug(`Ping sent to ${host}`); | ||
try { | ||
await client.ping(); | ||
clearTimeout(beatTimeoutId); | ||
debug(`Pong received from ${host}`); | ||
} catch (e) {} | ||
}, | ||
// mininum of a 10 second heartbeat | ||
Math.max(MIN_HEARTBEAT_INTERVAL, interval * 1000) | ||
); | ||
|
||
return () => { | ||
clearInterval(heartbeatIntervalId); | ||
clearTimeout(beatTimeoutId); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
const { expect } = require('chai'); | ||
|
||
const migrations = require('../../src/migrations/config-server'); | ||
const { migrate } = require('../../src/migrations'); | ||
|
||
const VERSION_UNDEFINED = { | ||
id: 'node.id', | ||
type: 'server', | ||
name: 'label of node', | ||
addon: false, | ||
}; | ||
const VERSION_0 = { | ||
...VERSION_UNDEFINED, | ||
version: 0, | ||
}; | ||
const VERSION_1 = { | ||
...VERSION_0, | ||
version: 1, | ||
rejectUnauthorizedCerts: true, | ||
ha_boolean: 'y|yes|true|on|home|open', | ||
connectionDelay: true, | ||
cacheJson: true, | ||
}; | ||
const VERSION_2 = { | ||
...VERSION_1, | ||
version: 2, | ||
heartbeat: false, | ||
heartbeatInterval: 30, | ||
}; | ||
|
||
describe('Migrations - Server Config Node', function () { | ||
describe('Version 0', function () { | ||
it('should add version 0 to schema when no version is defined', function () { | ||
const migrate = migrations.find((m) => m.version === 0); | ||
const migratedSchema = migrate.up(VERSION_UNDEFINED); | ||
expect(migratedSchema).to.eql(VERSION_0); | ||
}); | ||
}); | ||
describe('Version 1', function () { | ||
it('should update version 0 to version 1', function () { | ||
const migrate = migrations.find((m) => m.version === 1); | ||
const migratedSchema = migrate.up(VERSION_0); | ||
expect(migratedSchema).to.eql(VERSION_1); | ||
}); | ||
}); | ||
describe('Version 2', function () { | ||
it('should update version 1 to version 2', function () { | ||
const migrate = migrations.find((m) => m.version === 2); | ||
const migratedSchema = migrate.up(VERSION_1); | ||
expect(migratedSchema).to.eql(VERSION_2); | ||
}); | ||
}); | ||
it('should update an undefined version to current version', function () { | ||
const migratedSchema = migrate(VERSION_UNDEFINED); | ||
expect(migratedSchema).to.eql(VERSION_2); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.