README.md: formatting fixes
[e-mobility-charging-stations-simulator.git] / src / charging-station / ui-server / UIWebSocketServer.ts
CommitLineData
6c1761d4 1import type { IncomingMessage } from 'http';
8114d10e 2
0d8140bd 3import WebSocket from 'ws';
8114d10e 4
6c1761d4 5import type { ServerOptions } from '../../types/ConfigurationData';
8b0088bb 6import { WebSocketCloseEventStatusCode } from '../../types/WebSocket';
8114d10e 7import Configuration from '../../utils/Configuration';
675fa8e3 8import logger from '../../utils/Logger';
8114d10e
JB
9import Utils from '../../utils/Utils';
10import { AbstractUIServer } from './AbstractUIServer';
11import UIServiceFactory from './ui-services/UIServiceFactory';
a92929f1 12import { UIServiceUtils } from './ui-services/UIServiceUtils';
4198ad5c 13
32de5a57
LM
14const moduleName = 'UIWebSocketServer';
15
fe94fce0 16export default class UIWebSocketServer extends AbstractUIServer {
b153c0fd 17 public constructor(options?: ServerOptions) {
fe94fce0 18 super();
0d8140bd 19 this.server = new WebSocket.Server(options ?? Configuration.getUIServer().options);
4198ad5c
JB
20 }
21
22 public start(): void {
d200b695 23 this.server.on('connection', (socket: WebSocket, request: IncomingMessage): void => {
a92929f1
JB
24 const [protocol, version] = UIServiceUtils.getProtocolAndVersion(socket.protocol);
25 if (UIServiceUtils.isProtocolAndVersionSupported(protocol, version) === false) {
26 logger.error(
27 `${this.logPrefix(
28 moduleName,
29 'start.server.onconnection'
30 )} Unsupported UI protocol version: '${protocol}${version}'`
31 );
8b0088bb 32 socket.close(WebSocketCloseEventStatusCode.CLOSE_PROTOCOL_ERROR);
a92929f1 33 }
de9136ae 34 if (!this.uiServices.has(version)) {
178ac666 35 this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this));
4198ad5c
JB
36 }
37 // FIXME: check connection validity
6c8f5d90 38 socket.on('message', (rawData) => {
e7aeea18
JB
39 this.uiServices
40 .get(version)
6c8f5d90
JB
41 .requestHandler(rawData)
42 .catch(() => {
43 /* Error caught by AbstractUIService */
e7aeea18 44 });
4198ad5c
JB
45 });
46 socket.on('error', (error) => {
32de5a57
LM
47 logger.error(
48 `${this.logPrefix(moduleName, 'start.socket.onerror')} Error on WebSocket:`,
49 error
50 );
4198ad5c
JB
51 });
52 });
53 }
54
55 public stop(): void {
5a010bf0 56 this.chargingStations.clear();
4198ad5c
JB
57 }
58
02a6943a
JB
59 public sendRequest(request: string): void {
60 this.broadcastToClients(request);
61 }
62
63 public sendResponse(response: string): void {
db2336d9 64 // TODO: send response only to the client that sent the request
02a6943a 65 this.broadcastToClients(response);
178ac666
JB
66 }
67
0d2cec76
JB
68 public logPrefix(modName?: string, methodName?: string, prefixSuffix?: string): string {
69 const logMsgPrefix = prefixSuffix
70 ? `UI WebSocket Server ${prefixSuffix}`
71 : 'UI WebSocket Server';
32de5a57 72 const logMsg =
0d2cec76 73 modName && methodName ? ` ${logMsgPrefix} | ${modName}.${methodName}:` : ` ${logMsgPrefix} |`;
32de5a57 74 return Utils.logPrefix(logMsg);
4198ad5c 75 }
178ac666
JB
76
77 private broadcastToClients(message: string): void {
0d8140bd
JB
78 for (const client of (this.server as WebSocket.Server).clients) {
79 if (client?.readyState === WebSocket.OPEN) {
178ac666
JB
80 client.send(message);
81 }
82 }
83 }
4198ad5c 84}