diff --git a/main.js b/main.js index 462ce409f78fea45cb52746a1da6913205d581bf..8691d4dc53363c558ddb066e8975cf0785ea3a15 100644 --- a/main.js +++ b/main.js @@ -3,8 +3,13 @@ const UpgradeScripts = require('./upgrades') const UpdateActions = require('./actions') const UpdateFeedbacks = require('./feedbacks') const UpdateVariableDefinitions = require('./variables') +const WebSocket = require('ws') class ModuleInstance extends InstanceBase { + isInitialized = false + // language=RegExp + wsRegex = '^wss?:\\/\\/([\\da-z\\.-]+)(:\\d{1,5})?(?:\\/(.*))?$' + constructor(internal) { super(internal) } @@ -12,7 +17,8 @@ class ModuleInstance extends InstanceBase { async init(config) { this.config = config - this.updateStatus(InstanceStatus.Ok) + this.initWebSocket() + this.isInitialized = true this.updateActions() // export actions this.updateFeedbacks() // export feedbacks @@ -20,11 +26,17 @@ class ModuleInstance extends InstanceBase { } // When module gets deleted async destroy() { - this.log('debug', 'destroy') + this.isInitialized = false + + if (this.ws) { + this.ws.close(1000) + delete this.ws + } } async configUpdated(config) { this.config = config + this.initWebSocket() } // Return config fields for web config @@ -44,6 +56,13 @@ class ModuleInstance extends InstanceBase { width: 4, regex: Regex.PORT, }, + { + type: 'checkbox', + id: 'debug_messages', + label: 'Debug messages', + tooltip: 'Log incomming and outcomming messages', + width: 6, + }, ] } @@ -58,6 +77,63 @@ class ModuleInstance extends InstanceBase { updateVariableDefinitions() { UpdateVariableDefinitions(this) } + + // Websocket handling + + initWebSocket() { + if (this.reconnect_timer) { + clearTimeout(this.reconnect_timer) + this.reconnect_timer = null + } + + if (this.config.host == null || this.config.port == null) { + console.log(`PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`); + this.updateStatus(InstanceStatus.BadConfig, `PlayWall host '${this.config.host}' or port '${this.config.port}' is invalid`) + return + } + const url = `ws://${this.config.host}:${this.config.port}/api` + if (!url || url.match(new RegExp(this.wsRegex)) === null) { + this.updateStatus(InstanceStatus.BadConfig, `WS URL is not defined or invalid`) + return + } + + this.updateStatus(InstanceStatus.Connecting) + + if (this.ws) { + this.ws.close(1000) + delete this.ws + } + + this.ws = new WebSocket(url) + + this.ws.on('open', () => { + this.updateStatus(InstanceStatus.Ok) + this.log('debug', `Connection opened`) + }) + this.ws.on('close', (code) => { + this.log('debug', `Connection closed with code ${code}`) + this.updateStatus(InstanceStatus.Disconnected, `Connection closed with code ${code}`) + }) + + this.ws.on('message', this.messageReceivedFromWebSocket.bind(this)) + + this.ws.on('error', (data) => { + this.log('error', `WebSocket error: ${data}`) + }) + } + + messageReceivedFromWebSocket(data) { + if (this.config.debug_messages) { + this.log('debug', `Message received: ${data}`) + } + + let msgValue = null + try { + msgValue = JSON.parse(data) + } catch (e) { + msgValue = data + } + } } runEntrypoint(ModuleInstance, UpgradeScripts) diff --git a/package.json b/package.json index 17b2eb59111284cb701340eac8367a1322f39297..1fc3d144f7c47d2f540f9a8497410a1ab084e299 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "url": "git+https://github.com/bitfocus/companion-module-your-module-name.git" }, "dependencies": { - "@companion-module/base": "~1.4.0" + "@companion-module/base": "~1.4.0", + "ws": "^7.2.1" }, "devDependencies": { "@companion-module/tools": "^1.2.0"