Commit | Line | Data |
---|---|---|
178ac666 | 1 | import { Protocol, ProtocolVersion } from '../types/UIProtocol'; |
6a49ad23 | 2 | import WebSocket, { OPEN, Server, ServerOptions } from 'ws'; |
4198ad5c | 3 | |
383cb2ae | 4 | import AbstractUIService from './ui-websocket-services/AbstractUIService'; |
6a49ad23 | 5 | import Configuration from '../utils/Configuration'; |
4198ad5c | 6 | import { IncomingMessage } from 'http'; |
383cb2ae | 7 | import UIServiceFactory from './ui-websocket-services/UIServiceFactory'; |
4198ad5c | 8 | import Utils from '../utils/Utils'; |
9f2e3130 | 9 | import logger from '../utils/Logger'; |
4198ad5c | 10 | |
6a49ad23 | 11 | export default class UIWebSocketServer extends Server { |
de9136ae JB |
12 | public readonly chargingStations: Set<string>; |
13 | public readonly uiServices: Map<ProtocolVersion, AbstractUIService>; | |
4198ad5c | 14 | |
6a49ad23 | 15 | public constructor(options?: ServerOptions, callback?: () => void) { |
4198ad5c | 16 | // Create the WebSocket Server |
6a49ad23 | 17 | super(options ?? Configuration.getUIWebSocketServer().options, callback); |
de9136ae JB |
18 | this.chargingStations = new Set<string>(); |
19 | this.uiServices = new Map<ProtocolVersion, AbstractUIService>(); | |
4198ad5c JB |
20 | } |
21 | ||
22 | public start(): void { | |
23 | this.on('connection', (socket: WebSocket, request: IncomingMessage): void => { | |
24 | const protocolIndex = socket.protocol.indexOf(Protocol.UI); | |
e7aeea18 JB |
25 | const version = socket.protocol.substring( |
26 | protocolIndex + Protocol.UI.length | |
27 | ) as ProtocolVersion; | |
de9136ae | 28 | if (!this.uiServices.has(version)) { |
178ac666 | 29 | this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this)); |
4198ad5c JB |
30 | } |
31 | // FIXME: check connection validity | |
32 | socket.on('message', (messageData) => { | |
e7aeea18 JB |
33 | this.uiServices |
34 | .get(version) | |
178ac666 | 35 | .messageHandler(messageData) |
e7aeea18 | 36 | .catch(() => { |
178ac666 | 37 | logger.error(`${this.logPrefix()} Error while handling message data: %j`, messageData); |
e7aeea18 | 38 | }); |
4198ad5c JB |
39 | }); |
40 | socket.on('error', (error) => { | |
9f2e3130 | 41 | logger.error(`${this.logPrefix()} Error on WebSocket: %j`, error); |
4198ad5c JB |
42 | }); |
43 | }); | |
44 | } | |
45 | ||
46 | public stop(): void { | |
47 | this.close(); | |
48 | } | |
49 | ||
178ac666 JB |
50 | public sendResponse(message: string): void { |
51 | this.broadcastToClients(message); | |
52 | } | |
53 | ||
4198ad5c | 54 | public logPrefix(): string { |
410a760d | 55 | return Utils.logPrefix(' UI WebSocket Server:'); |
4198ad5c | 56 | } |
178ac666 JB |
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 | } | |
4198ad5c | 65 | } |