Apply prettier formating
[e-mobility-charging-stations-simulator.git] / src / charging-station / UIWebSocketServer.ts
CommitLineData
a10297ba 1import { Protocol, ProtocolCommand, ProtocolRequest, ProtocolVersion } from '../types/UIProtocol';
6a49ad23 2import WebSocket, { OPEN, Server, ServerOptions } from 'ws';
4198ad5c 3
383cb2ae 4import AbstractUIService from './ui-websocket-services/AbstractUIService';
4198ad5c 5import BaseError from '../exception/BaseError';
6a49ad23 6import Configuration from '../utils/Configuration';
4198ad5c 7import { IncomingMessage } from 'http';
383cb2ae 8import UIServiceFactory from './ui-websocket-services/UIServiceFactory';
4198ad5c 9import Utils from '../utils/Utils';
9f2e3130 10import logger from '../utils/Logger';
4198ad5c 11
6a49ad23 12export default class UIWebSocketServer extends Server {
de9136ae
JB
13 public readonly chargingStations: Set<string>;
14 public readonly uiServices: Map<ProtocolVersion, AbstractUIService>;
4198ad5c 15
6a49ad23 16 public constructor(options?: ServerOptions, callback?: () => void) {
4198ad5c 17 // Create the WebSocket Server
6a49ad23 18 super(options ?? Configuration.getUIWebSocketServer().options, callback);
de9136ae
JB
19 this.chargingStations = new Set<string>();
20 this.uiServices = new Map<ProtocolVersion, AbstractUIService>();
21 for (const version of Object.values(ProtocolVersion)) {
22 this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this));
23 }
4198ad5c
JB
24 }
25
d1888640 26 public broadcastToClients(message: string): void {
4198ad5c 27 for (const client of this.clients) {
6a49ad23 28 if (client?.readyState === OPEN) {
4198ad5c
JB
29 client.send(message);
30 }
31 }
32 }
33
34 public start(): void {
35 this.on('connection', (socket: WebSocket, request: IncomingMessage): void => {
36 const protocolIndex = socket.protocol.indexOf(Protocol.UI);
e7aeea18
JB
37 const version = socket.protocol.substring(
38 protocolIndex + Protocol.UI.length
39 ) as ProtocolVersion;
de9136ae 40 if (!this.uiServices.has(version)) {
e7aeea18
JB
41 throw new BaseError(
42 `Could not find a UI service implementation for UI protocol version ${version}`
43 );
4198ad5c
JB
44 }
45 // FIXME: check connection validity
46 socket.on('message', (messageData) => {
47 let [command, payload]: ProtocolRequest = [ProtocolCommand.UNKNOWN, {}];
48 const protocolRequest = JSON.parse(messageData.toString()) as ProtocolRequest;
49 if (Utils.isIterable(protocolRequest)) {
50 [command, payload] = protocolRequest;
51 } else {
410a760d 52 throw new BaseError('UI protocol request is not iterable');
4198ad5c 53 }
e7aeea18
JB
54 this.uiServices
55 .get(version)
56 .handleMessage(command, payload)
57 .catch(() => {
58 logger.error(
59 `${this.logPrefix()} Error while handling command %s message: %j`,
60 command,
61 payload
62 );
63 });
4198ad5c
JB
64 });
65 socket.on('error', (error) => {
9f2e3130 66 logger.error(`${this.logPrefix()} Error on WebSocket: %j`, error);
4198ad5c
JB
67 });
68 });
69 }
70
71 public stop(): void {
72 this.close();
73 }
74
75 public logPrefix(): string {
410a760d 76 return Utils.logPrefix(' UI WebSocket Server:');
4198ad5c
JB
77 }
78}