From be97f9c3f44100ac1209ee46c6b4fc90d60d7fc5 Mon Sep 17 00:00:00 2001 From: jgerstbe Date: Sun, 16 Aug 2020 23:53:37 +0200 Subject: [PATCH] [A] websockets for realtime updates on new images --- index.js | 43 +++++++++++++++++++++++++++++++------------ package-lock.json | 21 +++++++++++++++++++++ package.json | 1 + public/app.js | 13 +++++++++++++ 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/index.js b/index.js index deb925e..14a1baa 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,31 @@ const client = createClient( } ); +/** + * webserver + */ +const express = require('express'); +const { stringify } = require('querystring'); +const app = express(); + +const expressWs = require('express-ws')(app); +app.ws('/watchdog', function(ws, req) { + ws.on('message', function(msg) { + // echo + ws.send(msg); + }); +}); + +app.use('/files', express.static(path.join(__dirname, 'files'))); +app.get('/api/files', (req, res) => { + res.json({resource: db.get('files').value()}); +}); +app.use(express.static(path.join(__dirname, 'public'))); +app.listen(process.env.PORT, () => console.log(`Example app listening at http://localhost:${process.env.PORT}`)); + +/** + * backend functions + */ async function listDir(dir = process.env.WEBFRAME_PATH) { const directoryItems = await client.getDirectoryContents(dir); @@ -50,25 +75,19 @@ async function loadImages() { fs.writeFile(path+file.basename, blob, () => { db.get('files').push(file).write(); db.update('count', n => n + 1).write(); + // notify clients via ws + expressWs.getWss().clients.forEach(ws => ws.send(JSON.stringify({ + code: 201, + message: 'pls update' + }))); }); } } } - setTimeout(() => loadImages(), process.env.POLL_TIMEOUT); + setTimeout(() => loadImages(), 2000); //process.env.POLL_TIMEOUT); } catch (e) { console.error('[loadImages]', e); } } loadImages(); - -// webserver -const express = require('express'); -const app = express(); - -app.use('/files', express.static(path.join(__dirname, 'files'))); -app.get('/api/files', (req, res) => { - res.json({resource: db.get('files').value()}); -}); -app.use(express.static(path.join(__dirname, 'public'))); -app.listen(process.env.PORT, () => console.log(`Example app listening at http://localhost:${process.env.PORT}`)); diff --git a/package-lock.json b/package-lock.json index 94a05c4..702257a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -93,6 +93,11 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, "axios": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", @@ -475,6 +480,14 @@ "vary": "~1.1.2" } }, + "express-ws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-4.0.0.tgz", + "integrity": "sha512-KEyUw8AwRET2iFjFsI1EJQrJ/fHeGiJtgpYgEWG3yDv4l/To/m3a2GaYfeGyB3lsWdvbesjF5XCMx+SVBgAAYw==", + "requires": { + "ws": "^5.2.0" + } + }, "fast-xml-parser": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.17.4.tgz", @@ -1481,6 +1494,14 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", diff --git a/package.json b/package.json index 819d3a7..68ad452 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "dependencies": { "dotenv": "^8.2.0", "express": "^4.17.1", + "express-ws": "^4.0.0", "lowdb": "^1.0.0", "webdav": "^3.3.0" }, diff --git a/public/app.js b/public/app.js index 9cb5436..6bbefb3 100644 --- a/public/app.js +++ b/public/app.js @@ -49,6 +49,18 @@ new Vue({ ); return prom; }, + subscribeForNewData: function () { + const ws = new WebSocket(`ws://${window.location.host}/watchdog`); + ws.onmessage = (event) => { + if (event.data) { + const data = JSON.parse(event.data); + if (data.code === 201) { + console.log('NEW IMAGE/S'); // TODO toast + this.loadData(); + } + } + } + }, refreshVideoSrc: function () { // force video src reload this.videoSrc = null; @@ -132,6 +144,7 @@ new Vue({ }, mounted() { this.loadData().then(data => { + this.subscribeForNewData(); setTimeout(() => { this.animateCSS('.floatBtn.left', 'fadeInLeft'); this.animateCSS('.floatBtn.right', 'fadeInRight');