Refine UI WS service log messages
[e-mobility-charging-stations-simulator.git] / src / charging-station / UIWebSocketServer.ts
1 import { Protocol, ProtocolCommand, ProtocolRequest, ProtocolVersion } from '../types/UIProtocol';
2
3 import AbstractUIService from './UIWebSocketServices/AbstractUIService';
4 import BaseError from '../exception/BaseError';
5 import { IncomingMessage } from 'http';
6 import UIServiceFactory from './UIWebSocketServices/UIServiceFactory';
7 import Utils from '../utils/Utils';
8 import WebSocket from 'ws';
9 import logger from '../utils/Logger';
10
11 export default class UIWebSocketServer extends WebSocket.Server {
12 public uiService: AbstractUIService;
13
14 public constructor(options?: WebSocket.ServerOptions, callback?: () => void) {
15 // Create the WebSocket Server
16 super(options ?? { port: 80 }, callback);
17 }
18
19 public broadcastToClients(message: string | Record<string, unknown>): void {
20 for (const client of this.clients) {
21 if (client?.readyState === WebSocket.OPEN) {
22 client.send(message);
23 }
24 }
25 }
26
27 public start(): void {
28 this.on('connection', (socket: WebSocket, request: IncomingMessage): void => {
29 const protocolIndex = socket.protocol.indexOf(Protocol.UI);
30 const version = socket.protocol.substring(protocolIndex + Protocol.UI.length) as ProtocolVersion;
31 this.uiService = UIServiceFactory.getUIServiceImplementation(version, this);
32 if (!this.uiService) {
33 throw new BaseError(`Could not find a UI service implementation for UI protocol version ${version}`);
34 }
35 // FIXME: check connection validity
36 socket.on('message', (messageData) => {
37 let [command, payload]: ProtocolRequest = [ProtocolCommand.UNKNOWN, {}];
38 const protocolRequest = JSON.parse(messageData.toString()) as ProtocolRequest;
39 if (Utils.isIterable(protocolRequest)) {
40 [command, payload] = protocolRequest;
41 } else {
42 throw new BaseError('UI protocol request is not iterable');
43 }
44 this.uiService.handleMessage(command, payload).catch(() => {
45 logger.error(`${this.logPrefix()} Error while handling command %s message: %j`, command, payload);
46 });
47 });
48 socket.on('error', (error) => {
49 logger.error(`${this.logPrefix()} Error on WebSocket: %j`, error);
50 });
51 });
52 }
53
54 public stop(): void {
55 this.close();
56 }
57
58 public logPrefix(): string {
59 return Utils.logPrefix(' UI WebSocket Server:');
60 }
61 }