From 38f5d3b66ae56174c521a32a02e2e3c03ad00d46 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 May 2021 17:17:24 +0200 Subject: [PATCH] Added WebSockets with funcionality to send messages from any module --- Socket.js | 21 +++++++++++++++++++++ Sockets.js | 20 ++++++++++++++++++++ api.js | 21 +++++++++++++++++++++ package-lock.json | 5 +++++ package.json | 3 ++- server.js | 33 +++++++++++++-------------------- utils/jobs.js | 2 ++ 7 files changed, 84 insertions(+), 21 deletions(-) create mode 100644 Socket.js create mode 100644 Sockets.js create mode 100644 api.js diff --git a/Socket.js b/Socket.js new file mode 100644 index 0000000..5b6d05c --- /dev/null +++ b/Socket.js @@ -0,0 +1,21 @@ +const WebSocket = require('ws'); + +class Socket { + constructor(server) { + this.webSocketServer = new WebSocket.Server({ server }) + + this.webSocketServer.on('listening', () => { + console.log('socket listen'); + }) + + this.webSocketServer.on('connection', (webSocketClient) => { + console.log('new connection'); + }) + } + + send(msg) { + this.webSocketServer.clients.forEach(client => client.send(msg)); + } +} + +module.exports = Socket; \ No newline at end of file diff --git a/Sockets.js b/Sockets.js new file mode 100644 index 0000000..3457aa5 --- /dev/null +++ b/Sockets.js @@ -0,0 +1,20 @@ +class Sockets { + constructor() { + this.sockets = []; + } + + registerSocket(name, socket) { + this.sockets.push({ name, socket }); + } + + getAllSockets() { + return this.sockets; + } + + getSocket(name) { + const socket = this.sockets.find(socket => socket.name === name); + return socket; + } +} + +module.exports = new Sockets(); \ No newline at end of file diff --git a/api.js b/api.js new file mode 100644 index 0000000..31151da --- /dev/null +++ b/api.js @@ -0,0 +1,21 @@ +const express = require('express'); +const errorHandler = require('./middleware/errorHandler'); + +const api = express(); + +api.get('/', (req, res) => { + res.send('Server is working'); +}) + +// Body parser +api.use(express.json()); + +// Link controllers with routes +api.use('/api/apps', require('./routes/apps')); +api.use('/api/config', require('./routes/config')); +api.use('/api/weather', require('./routes/weather')); + +// Custom error handler +api.use(errorHandler); + +module.exports = api; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9d9cbf5..4726a7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2793,6 +2793,11 @@ "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.5.tgz", + "integrity": "sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==" + }, "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 c3e063f..e6c92ed 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "express": "^4.17.1", "node-schedule": "^2.0.0", "sequelize": "^6.6.2", - "sqlite3": "^5.0.2" + "sqlite3": "^5.0.2", + "ws": "^7.4.5" }, "devDependencies": { "nodemon": "^2.0.7" diff --git a/server.js b/server.js index d9e510f..a502846 100644 --- a/server.js +++ b/server.js @@ -1,30 +1,23 @@ -const express = require('express'); +const http = require('http'); const { connectDB } = require('./db'); -const errorHandler = require('./middleware/errorHandler'); +const api = require('./api'); const jobs = require('./utils/jobs'); -const colors = require('colors'); +const Socket = require('./Socket'); +const Sockets = require('./Sockets'); + require('dotenv').config(); +const PORT = process.env.PORT || 5005; connectDB(); -const app = express(); -const PORT = process.env.PORT || 5005; +// Create server for Express API and WebSockets +const server = http.createServer(); +server.on('request', api); -app.get('/', (req, res) => { - res.send('Server is working'); -}) +// Register weatherSocket +const weatherSocket = new Socket(server); +Sockets.registerSocket('weather', weatherSocket); -// Body parser -app.use(express.json()); - -// Link controllers with routes -app.use('/api/apps', require('./routes/apps')); -app.use('/api/config', require('./routes/config')); -app.use('/api/weather', require('./routes/weather')); - -// Custom error handler -app.use(errorHandler); - -app.listen(PORT, () => { +server.listen(PORT, () => { console.log(`Server is running on port ${PORT} in ${process.env.NODE_ENV} mode`.yellow.bold); }) \ No newline at end of file diff --git a/utils/jobs.js b/utils/jobs.js index 1243f2f..4c4747e 100644 --- a/utils/jobs.js +++ b/utils/jobs.js @@ -1,10 +1,12 @@ const schedule = require('node-schedule'); const getExternalWeather = require('./getExternalWeather'); +const Sockets = require('../Sockets'); const weatherJob = schedule.scheduleJob('updateWeather', '0 */15 * * * *', async () => { try { await getExternalWeather(); console.log('weather updated'); + Sockets.getSocket('weather').socket.send('weather updated'); } catch (err) { console.log(err); }