From 5ac4a6275b57a792aba7d7cafda696db8630344c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Majdand=C5=BEi=C4=87?= Date: Fri, 24 Mar 2023 16:16:13 +0100 Subject: [PATCH] Implement websocket server --- main.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++- package.json | 3 ++- websocketTest.js | 12 +++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 websocketTest.js diff --git a/main.js b/main.js index 85674de..2340dc0 100644 --- a/main.js +++ b/main.js @@ -7,8 +7,10 @@ const EventEmitter = require('events'); const express = require('express'); const app = express(); const bodyParser = require('body-parser'); +const WebSocket = require('ws'); const SERVER_PORT = process.env.SERVER_PORT || 8190; +const WS_SERVER_PORT = process.env.WS_SERVER_PORT || 8191; [ @@ -411,6 +413,71 @@ class HTTPServer { } } +class WSServer { + // Have clients be grouped by session ID + // Any change on a session should be broadcasted to all clients in that session + // Clients make their session ID known by sending a message with the session ID + // It is possible to move clients by changing their session ID + clients = {}; + + constructor() { + this.server = new WebSocket.Server({port: WS_SERVER_PORT}); + this.logger = new Logger("WSServer"); + this.server.on('connection', this.onConnection.bind(this)); + this.logger.log1(`WSServer listening at ws://localhost:${WS_SERVER_PORT}`); + } + + onConnection(ws) { + this.logger.log1("New connection"); + this.addClient(ws, -1); + ws.on('message', this.onMessage.bind(this, ws)); + ws.on('close', this.onClose.bind(this, ws)); + } + + addClient(ws, sessionId) { + if (!this.clients[sessionId]) { + this.clients[sessionId] = []; + } + this.logger.log1(`Added client to session ID: ${sessionId}`); + this.clients[sessionId].push(ws); + this.logger.log1(`Now active ${this.clients[sessionId].length} clients in session ID: ${sessionId}`); + } + + onMessage(ws, message) { + this.logger.log1("New message"); + let sessionId = String(message); + this.logger.log1(`Moving client to session ID: ${sessionId}`); + this.removeClient(ws); + this.addClient(ws, sessionId); + this.logger.log1(`Now active ${this.clients[sessionId].length} clients in session ID: ${sessionId}`); + } + + onClose(ws) { + this.removeClient(ws); + this.logger.log6(this.clients); + this.logger.log1("Connection closed"); + } + + removeClient(ws) { + for (let sessionId in this.clients) { + let index = this.clients[sessionId].indexOf(ws); + if (index > -1) { + delete this.clients[sessionId][index]; + } + } + this.cleanClients(); + } + + cleanClients() { + for (let sessionId in this.clients) { + this.clients[sessionId] = this.clients[sessionId].filter(Boolean); + if (this.clients[sessionId].length === 0) { + delete this.clients[sessionId]; + } + } + } +} + function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); @@ -436,4 +503,5 @@ session.on('statusChanged', (status) => { // sleep(600 * 1000); // }); // }); -let httpServer = new HTTPServer(); \ No newline at end of file +new WSServer(); +new HTTPServer(); \ No newline at end of file diff --git a/package.json b/package.json index e1ee03b..6ca6d19 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "body-parser": "^1.20.2", "express": "^4.18.2", "keyboardjs": "^2.7.0", - "smpp": "^0.6.0-rc.4" + "smpp": "^0.6.0-rc.4", + "ws": "^8.13.0" } } diff --git a/websocketTest.js b/websocketTest.js new file mode 100644 index 0000000..1667615 --- /dev/null +++ b/websocketTest.js @@ -0,0 +1,12 @@ +const WebSocket = require('ws'); + +const WS_SERVER_PORT = process.env.WS_SERVER_PORT || 8191; + +const ws = new WebSocket(`ws://localhost:${WS_SERVER_PORT}`); +ws.on('open', () => { + console.log('WebSocket connection established'); + ws.send(3); +}); +ws.on('message', (data) => { + console.log(data); +}); \ No newline at end of file