From 94dc30801f06da3ae0bb9c3bb73ff29dbbf96b6e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 8 Sep 2022 00:16:21 +0200 Subject: [PATCH] UI Server: factor out responses handling logic in abstract class MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .../ui-server/AbstractUIServer.ts | 7 +++--- .../ui-server/UIHttpServer.ts | 15 ++---------- .../ui-server/UIWebSocketServer.ts | 24 ++++++++++++++----- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/charging-station/ui-server/AbstractUIServer.ts b/src/charging-station/ui-server/AbstractUIServer.ts index f6e2010f..75f6e8a8 100644 --- a/src/charging-station/ui-server/AbstractUIServer.ts +++ b/src/charging-station/ui-server/AbstractUIServer.ts @@ -1,5 +1,4 @@ -import { type IncomingMessage, Server } from 'http'; -import type { Socket } from 'net'; +import { type IncomingMessage, Server, type ServerResponse } from 'http'; import type { WebSocket } from 'ws'; @@ -20,13 +19,13 @@ import UIServiceFactory from './ui-services/UIServiceFactory'; export abstract class AbstractUIServer { public readonly chargingStations: Map; protected httpServer: Server; - protected sockets: Set; + protected responseHandlers: Map; protected readonly uiServices: Map; public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { this.chargingStations = new Map(); this.httpServer = new Server(); - this.sockets = new Set(); + this.responseHandlers = new Map(); this.uiServices = new Map(); } diff --git a/src/charging-station/ui-server/UIHttpServer.ts b/src/charging-station/ui-server/UIHttpServer.ts index d6ce5310..d1615dbb 100644 --- a/src/charging-station/ui-server/UIHttpServer.ts +++ b/src/charging-station/ui-server/UIHttpServer.ts @@ -20,23 +20,12 @@ import { UIServiceUtils } from './ui-services/UIServiceUtils'; const moduleName = 'UIHttpServer'; -type responseHandler = { procedureName: ProcedureName; res: ServerResponse }; - export default class UIHttpServer extends AbstractUIServer { - private readonly responseHandlers: Map; - public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { super(uiServerConfiguration); - this.responseHandlers = new Map(); } public start(): void { - this.httpServer.on('connection', (socket) => { - this.sockets.add(socket); - socket.on('close', () => { - this.sockets.delete(socket); - }); - }); this.httpServer.on('request', this.requestListener.bind(this) as RequestListener); if (this.httpServer.listening === false) { this.httpServer.listen(this.uiServerConfiguration.options); @@ -51,7 +40,7 @@ export default class UIHttpServer extends AbstractUIServer { public sendResponse(response: ProtocolResponse): void { const [uuid, payload] = response; if (this.responseHandlers.has(uuid) === true) { - const { res } = this.responseHandlers.get(uuid); + const res = this.responseHandlers.get(uuid) as ServerResponse; res.writeHead(this.responseStatusToStatusCode(payload.status), { 'Content-Type': 'application/json', }); @@ -86,7 +75,7 @@ export default class UIHttpServer extends AbstractUIServer { ProcedureName ]; const uuid = Utils.generateUUID(); - this.responseHandlers.set(uuid, { procedureName, res }); + this.responseHandlers.set(uuid, res); try { if (UIServiceUtils.isProtocolAndVersionSupported(protocol, version) === false) { throw new BaseError(`Unsupported UI protocol version: '/${protocol}/${version}'`); diff --git a/src/charging-station/ui-server/UIWebSocketServer.ts b/src/charging-station/ui-server/UIWebSocketServer.ts index bb80c60a..ce773db3 100644 --- a/src/charging-station/ui-server/UIWebSocketServer.ts +++ b/src/charging-station/ui-server/UIWebSocketServer.ts @@ -38,7 +38,6 @@ export default class UIWebSocketServer extends AbstractUIServer { ); ws.close(WebSocketCloseEventStatusCode.CLOSE_PROTOCOL_ERROR); } - this.sockets.add(ws); this.registerProtocolVersionUIService(version); ws.on('message', (rawData) => { const request = this.validateRawDataRequest(rawData); @@ -46,10 +45,11 @@ export default class UIWebSocketServer extends AbstractUIServer { ws.close(WebSocketCloseEventStatusCode.CLOSE_INVALID_PAYLOAD); return; } - const [messageId, procedureName, payload] = request as ProtocolRequest; + const [requestId] = request as ProtocolRequest; + this.responseHandlers.set(requestId, ws); this.uiServices .get(version) - .requestHandler(this.buildProtocolRequest(messageId, procedureName, payload)) + .requestHandler(request) .catch(() => { /* Error caught by AbstractUIService */ }); @@ -58,7 +58,6 @@ export default class UIWebSocketServer extends AbstractUIServer { logger.error(`${this.logPrefix(moduleName, 'start.ws.onerror')} WebSocket error:`, error); }); ws.on('close', (code, reason) => { - this.sockets.delete(ws); logger.debug( `${this.logPrefix( moduleName, @@ -94,8 +93,21 @@ export default class UIWebSocketServer extends AbstractUIServer { } public sendResponse(response: ProtocolResponse): void { - // TODO: send response only to the client that sent the request - this.broadcastToClients(JSON.stringify(response)); + const responseId = response[0]; + if (this.responseHandlers.has(responseId)) { + const ws = this.responseHandlers.get(responseId) as WebSocket; + if (ws?.readyState === WebSocket.OPEN) { + ws.send(JSON.stringify(response)); + } + this.responseHandlers.delete(responseId); + } else { + logger.error( + `${this.logPrefix( + moduleName, + 'sendResponse' + )} Response for unknown request id: ${responseId}` + ); + } } public logPrefix(modName?: string, methodName?: string, prefixSuffix?: string): string { -- 2.34.1