Commit | Line | Data |
---|---|---|
4198ad5c | 1 | import { IncomingMessage } from 'http'; |
8114d10e | 2 | |
0d8140bd | 3 | import WebSocket from 'ws'; |
8114d10e JB |
4 | |
5 | import { ServerOptions } from '../../types/ConfigurationData'; | |
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 | |
31 | socket.on('message', (messageData) => { | |
e7aeea18 JB |
32 | this.uiServices |
33 | .get(version) | |
178ac666 | 34 | .messageHandler(messageData) |
32de5a57 LM |
35 | .catch((error) => { |
36 | logger.error( | |
37 | `${this.logPrefix( | |
38 | moduleName, | |
39 | 'start.socket.onmessage' | |
40 | )} Error while handling message:`, | |
41 | error | |
42 | ); | |
e7aeea18 | 43 | }); |
4198ad5c JB |
44 | }); |
45 | socket.on('error', (error) => { | |
32de5a57 LM |
46 | logger.error( |
47 | `${this.logPrefix(moduleName, 'start.socket.onerror')} Error on WebSocket:`, | |
48 | error | |
49 | ); | |
4198ad5c JB |
50 | }); |
51 | }); | |
52 | } | |
53 | ||
54 | public stop(): void { | |
d200b695 | 55 | this.server.close(); |
4198ad5c JB |
56 | } |
57 | ||
178ac666 JB |
58 | public sendResponse(message: string): void { |
59 | this.broadcastToClients(message); | |
60 | } | |
61 | ||
32de5a57 LM |
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); | |
4198ad5c | 68 | } |
178ac666 JB |
69 | |
70 | private broadcastToClients(message: string): void { | |
0d8140bd JB |
71 | for (const client of (this.server as WebSocket.Server).clients) { |
72 | if (client?.readyState === WebSocket.OPEN) { | |
178ac666 JB |
73 | client.send(message); |
74 | } | |
75 | } | |
76 | } | |
4198ad5c | 77 | } |