From 9175a81fb0a71b92b638c12decd73750918248ea Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Thu, 18 Jul 2019 18:59:48 +0200 Subject: [PATCH] feat(connect): use stable prot for builtin server --- scripts/connect.ts | 5 +++++ scripts/device/portForDevice.ts | 11 +++++++++++ scripts/device/ui-server.ts | 4 +++- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 scripts/device/portForDevice.ts diff --git a/scripts/connect.ts b/scripts/connect.ts index f53f0d20..d5d74a77 100644 --- a/scripts/connect.ts +++ b/scripts/connect.ts @@ -10,6 +10,10 @@ import { uiServer } from './device/ui-server' */ const main = async (args: { deviceId: string }) => { const clientId = args.deviceId + if (!clientId || !clientId.length) { + throw new Error('Must provide a device id!') + } + console.log(chalk.magenta('Fetching IoT endpoint address ...')) const { endpointAddress } = await new Iot({ region: process.env.AWS_DEFAULT_REGION, }) @@ -54,6 +58,7 @@ const main = async (args: { deviceId: string }) => { connection.register(clientId, {}, async () => { await uiServer({ + deviceId: clientId, onUpdate: update => { console.log({ clientId, state: { state: { reported: update } } }) connection.update(clientId, { state: { reported: update } }) diff --git a/scripts/device/portForDevice.ts b/scripts/device/portForDevice.ts new file mode 100644 index 00000000..01e891db --- /dev/null +++ b/scripts/device/portForDevice.ts @@ -0,0 +1,11 @@ +/** + * Calculates a stable port number based on the device id + */ +export const portForDevice = ({ deviceId }: { deviceId: string }): number => { + let hash = 0 + for (let i = 0; i < deviceId.length; i++) { + hash = (hash << 5) - hash + deviceId.charCodeAt(i) + hash |= 0 // Convert to 32bit integer + } + return 1024 + Math.round((hash / Math.pow(2, 31)) * (65535 - 1024)) +} diff --git a/scripts/device/ui-server.ts b/scripts/device/ui-server.ts index 5221d45d..3008eb73 100644 --- a/scripts/device/ui-server.ts +++ b/scripts/device/ui-server.ts @@ -2,11 +2,13 @@ import * as path from 'path' import * as http from 'http' import { promises as fs } from 'fs' import chalk from 'chalk' +import { portForDevice } from './portForDevice' export const uiServer = async (args: { + deviceId: string onUpdate: (update: object) => void }) => { - const port = 1024 + Math.round(Math.random() * (65535 - 1024)) + const port = portForDevice({ deviceId: args.deviceId }) const uiPage = await fs.readFile( path.resolve(process.cwd(), 'data', 'device-ui.html'), 'utf-8',