Refine UI server attributes scope and type
[e-mobility-charging-stations-simulator.git] / src / charging-station / ui-server / UIWebSocketServer.ts
1 import { Protocol, ProtocolVersion } from '../../types/UIProtocol';
2 import WebSocket, { OPEN, Server, ServerOptions } from 'ws';
3
4 import AbstractUIService from './ui-services/AbstractUIService';
5 import Configuration from '../../utils/Configuration';
6 import { IncomingMessage } from 'http';
7 import UIServiceFactory from './ui-services/UIServiceFactory';
8 import Utils from '../../utils/Utils';
9 import logger from '../../utils/Logger';
10
11 export default class UIWebSocketServer extends Server {
12 public readonly chargingStations: Set<string>;
13 private readonly uiServices: Map<ProtocolVersion, AbstractUIService>;
14
15 public constructor(options?: ServerOptions, callback?: () => void) {
16 // Create the WebSocket Server
17 super(options ?? Configuration.getUIServer().options, callback);
18 this.chargingStations = new Set<string>();
19 this.uiServices = new Map<ProtocolVersion, AbstractUIService>();
20 }
21
22 public start(): void {
23 this.on('connection', (socket: WebSocket, request: IncomingMessage): void => {
24 const protocolIndex = socket.protocol.indexOf(Protocol.UI);
25 const version = socket.protocol.substring(
26 protocolIndex + Protocol.UI.length
27 ) as ProtocolVersion;
28 if (!this.uiServices.has(version)) {
29 this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this));
30 }
31 // FIXME: check connection validity
32 socket.on('message', (messageData) => {
33 this.uiServices
34 .get(version)
35 .messageHandler(messageData)
36 .catch(() => {
37 logger.error(`${this.logPrefix()} Error while handling message data: %j`, messageData);
38 });
39 });
40 socket.on('error', (error) => {
41 logger.error(`${this.logPrefix()} Error on WebSocket: %j`, error);
42 });
43 });
44 }
45
46 public stop(): void {
47 this.close();
48 }
49
50 public sendResponse(message: string): void {
51 this.broadcastToClients(message);
52 }
53
54 public logPrefix(): string {
55 return Utils.logPrefix(' UI WebSocket Server:');
56 }
57
58 private broadcastToClients(message: string): void {
59 for (const client of this.clients) {
60 if (client?.readyState === OPEN) {
61 client.send(message);
62 }
63 }
64 }
65 }