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