Commit | Line | Data |
---|---|---|
6c1761d4 | 1 | import type { IncomingMessage } from 'http'; |
8114d10e | 2 | |
0d8140bd | 3 | import WebSocket from 'ws'; |
8114d10e | 4 | |
6c1761d4 | 5 | import type { ServerOptions } from '../../types/ConfigurationData'; |
8114d10e JB |
6 | import { Protocol, ProtocolVersion } from '../../types/UIProtocol'; |
7 | import Configuration from '../../utils/Configuration'; | |
675fa8e3 | 8 | import logger from '../../utils/Logger'; |
8114d10e JB |
9 | import Utils from '../../utils/Utils'; |
10 | import { AbstractUIServer } from './AbstractUIServer'; | |
11 | import UIServiceFactory from './ui-services/UIServiceFactory'; | |
4198ad5c | 12 | |
32de5a57 LM |
13 | const moduleName = 'UIWebSocketServer'; |
14 | ||
fe94fce0 | 15 | export default class UIWebSocketServer extends AbstractUIServer { |
b153c0fd | 16 | public constructor(options?: ServerOptions) { |
fe94fce0 | 17 | super(); |
0d8140bd | 18 | this.server = new WebSocket.Server(options ?? Configuration.getUIServer().options); |
4198ad5c JB |
19 | } |
20 | ||
21 | public start(): void { | |
d200b695 | 22 | this.server.on('connection', (socket: WebSocket, request: IncomingMessage): void => { |
4198ad5c | 23 | const protocolIndex = socket.protocol.indexOf(Protocol.UI); |
e7aeea18 JB |
24 | const version = socket.protocol.substring( |
25 | protocolIndex + Protocol.UI.length | |
26 | ) as ProtocolVersion; | |
de9136ae | 27 | if (!this.uiServices.has(version)) { |
178ac666 | 28 | this.uiServices.set(version, UIServiceFactory.getUIServiceImplementation(version, this)); |
4198ad5c JB |
29 | } |
30 | // FIXME: check connection validity | |
6c8f5d90 | 31 | socket.on('message', (rawData) => { |
e7aeea18 JB |
32 | this.uiServices |
33 | .get(version) | |
6c8f5d90 JB |
34 | .requestHandler(rawData) |
35 | .catch(() => { | |
36 | /* Error caught by AbstractUIService */ | |
e7aeea18 | 37 | }); |
4198ad5c JB |
38 | }); |
39 | socket.on('error', (error) => { | |
32de5a57 LM |
40 | logger.error( |
41 | `${this.logPrefix(moduleName, 'start.socket.onerror')} Error on WebSocket:`, | |
42 | error | |
43 | ); | |
4198ad5c JB |
44 | }); |
45 | }); | |
46 | } | |
47 | ||
48 | public stop(): void { | |
5a010bf0 | 49 | this.chargingStations.clear(); |
4198ad5c JB |
50 | } |
51 | ||
02a6943a JB |
52 | public sendRequest(request: string): void { |
53 | this.broadcastToClients(request); | |
54 | } | |
55 | ||
56 | public sendResponse(response: string): void { | |
db2336d9 | 57 | // TODO: send response only to the client that sent the request |
02a6943a | 58 | this.broadcastToClients(response); |
178ac666 JB |
59 | } |
60 | ||
32de5a57 LM |
61 | public logPrefix(modName?: string, methodName?: string): string { |
62 | const logMsg = | |
63 | modName && methodName | |
64 | ? ` UI WebSocket Server | ${modName}.${methodName}:` | |
65 | : ' UI WebSocket Server |'; | |
66 | return Utils.logPrefix(logMsg); | |
4198ad5c | 67 | } |
178ac666 JB |
68 | |
69 | private broadcastToClients(message: string): void { | |
0d8140bd JB |
70 | for (const client of (this.server as WebSocket.Server).clients) { |
71 | if (client?.readyState === WebSocket.OPEN) { | |
178ac666 JB |
72 | client.send(message); |
73 | } | |
74 | } | |
75 | } | |
4198ad5c | 76 | } |