@nsshunt/stsappframework 3.0.104 → 3.0.106
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/influxdb/influxDBManager.js +16 -17
- package/dist/influxdb/influxDBManager.js.map +1 -1
- package/dist/influxdb/influxDBManagerAgent.js +9 -13
- package/dist/influxdb/influxDBManagerAgent.js.map +1 -1
- package/dist/influxdb/influxDBManagerBase.js +2 -6
- package/dist/influxdb/influxDBManagerBase.js.map +1 -1
- package/dist/influxdb/influxDBManagerService.js +10 -14
- package/dist/influxdb/influxDBManagerService.js.map +1 -1
- package/dist/instrumentationsubscriber.js +11 -15
- package/dist/instrumentationsubscriber.js.map +1 -1
- package/dist/kafka/IMKafkaManager.js +2 -6
- package/dist/kafka/IMKafkaManager.js.map +1 -1
- package/dist/kafkatesting/produce.js +1 -5
- package/dist/kafkatesting/produce.js.map +1 -1
- package/dist/processbase.js +7 -8
- package/dist/processbase.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/tcpclient/app2.js +2 -2
- package/dist/tcpserver/appmaster.js +39 -16
- package/dist/tcpserver/appmaster.js.map +1 -1
- package/package.json +7 -7
- package/src/influxdb/influxDBManager.ts +16 -18
- package/src/influxdb/influxDBManagerAgent.ts +9 -11
- package/src/influxdb/influxDBManagerBase.ts +2 -4
- package/src/influxdb/influxDBManagerService.ts +10 -12
- package/src/instrumentationsubscriber.ts +11 -14
- package/src/kafka/IMKafkaManager.ts +2 -4
- package/src/kafkatesting/produce.ts +1 -3
- package/src/processbase.ts +7 -9
- package/src/server.ts +1 -1
- package/src/tcpclient/app2.ts +2 -2
- package/src/tcpserver/appmaster.ts +39 -17
- package/types/influxdb/influxDBManager.d.ts.map +1 -1
- package/types/influxdb/influxDBManagerAgent.d.ts.map +1 -1
- package/types/influxdb/influxDBManagerBase.d.ts.map +1 -1
- package/types/influxdb/influxDBManagerService.d.ts.map +1 -1
- package/types/instrumentationsubscriber.d.ts.map +1 -1
- package/types/kafka/IMKafkaManager.d.ts.map +1 -1
- package/types/processbase.d.ts +2 -2
- package/types/processbase.d.ts.map +1 -1
- package/types/tcpserver/appmaster.d.ts.map +1 -1
- package/src_working/authDefs.ts +0 -37
- package/src_working/authutilsnode.ts +0 -373
- package/src_working/commonTypes.ts +0 -239
- package/src_working/index.ts +0 -22
- package/src_working/influxdb/influxDBManager.ts +0 -970
- package/src_working/influxdb/influxDBManagerAgent.ts +0 -314
- package/src_working/influxdb/influxDBManagerBase.ts +0 -109
- package/src_working/influxdb/influxDBManagerService.ts +0 -373
- package/src_working/instrumentationsubscriber.ts +0 -283
- package/src_working/kafka/IMKafkaManager.ts +0 -152
- package/src_working/kafka/kafkaconsumer.ts +0 -82
- package/src_working/kafka/kafkamanager.ts +0 -186
- package/src_working/kafka/kafkaproducer.ts +0 -58
- package/src_working/kafkatesting/config.ts +0 -10
- package/src_working/kafkatesting/consume.ts +0 -116
- package/src_working/kafkatesting/produce.ts +0 -153
- package/src_working/masterprocessbase.ts +0 -598
- package/src_working/middleware/serverNetworkMiddleware.ts +0 -240
- package/src_working/network.ts +0 -36
- package/src_working/processbase.ts +0 -411
- package/src_working/processoptions.ts +0 -164
- package/src_working/publishertransports/publishTransportDirect.ts +0 -45
- package/src_working/publishertransports/publishTransportUtils.ts +0 -53
- package/src_working/server.ts +0 -141
- package/src_working/serverprocessbase.ts +0 -393
- package/src_working/singleprocessbase.ts +0 -121
- package/src_working/socketIoServerHelper.ts +0 -177
- package/src_working/stscontrollerbase.ts +0 -15
- package/src_working/stslatencycontroller.ts +0 -27
- package/src_working/stslatencyroute.ts +0 -16
- package/src_working/stsrouterbase.ts +0 -22
- package/src_working/tcpclient/app.ts +0 -19
- package/src_working/tcpclient/app2.ts +0 -56
- package/src_working/tcpserver/app.ts +0 -11
- package/src_working/tcpserver/appConfig.ts +0 -65
- package/src_working/tcpserver/appmaster.ts +0 -544
- package/src_working/validation/errors.ts +0 -6
- package/src_working/webworkertesting/app.ts +0 -49
- package/src_working/webworkertesting/worker.ts +0 -24
- package/src_working/workerprocessbase.test.ts +0 -47
- package/src_working/workerprocessbase.ts +0 -185
- package/src_working2/authDefs.ts +0 -37
- package/src_working2/authutilsnode.ts +0 -375
- package/src_working2/commonTypes.ts +0 -239
- package/src_working2/index.ts +0 -22
- package/src_working2/influxdb/influxDBManager.ts +0 -972
- package/src_working2/influxdb/influxDBManagerAgent.ts +0 -316
- package/src_working2/influxdb/influxDBManagerBase.ts +0 -111
- package/src_working2/influxdb/influxDBManagerService.ts +0 -375
- package/src_working2/instrumentationsubscriber.ts +0 -286
- package/src_working2/kafka/IMKafkaManager.ts +0 -154
- package/src_working2/kafka/kafkaconsumer.ts +0 -82
- package/src_working2/kafka/kafkamanager.ts +0 -186
- package/src_working2/kafka/kafkaproducer.ts +0 -58
- package/src_working2/kafkatesting/config.ts +0 -10
- package/src_working2/kafkatesting/consume.ts +0 -116
- package/src_working2/kafkatesting/produce.ts +0 -155
- package/src_working2/masterprocessbase.ts +0 -590
- package/src_working2/middleware/serverNetworkMiddleware.ts +0 -240
- package/src_working2/network.ts +0 -36
- package/src_working2/processbase.ts +0 -415
- package/src_working2/processoptions.ts +0 -164
- package/src_working2/publishertransports/publishTransportDirect.ts +0 -45
- package/src_working2/publishertransports/publishTransportUtils.ts +0 -53
- package/src_working2/server.ts +0 -141
- package/src_working2/serverprocessbase.ts +0 -393
- package/src_working2/singleprocessbase.ts +0 -123
- package/src_working2/socketIoServerHelper.ts +0 -177
- package/src_working2/stscontrollerbase.ts +0 -15
- package/src_working2/stslatencycontroller.ts +0 -27
- package/src_working2/stslatencyroute.ts +0 -16
- package/src_working2/stsrouterbase.ts +0 -22
- package/src_working2/tcpclient/app.ts +0 -19
- package/src_working2/tcpclient/app2.ts +0 -56
- package/src_working2/tcpserver/app.ts +0 -11
- package/src_working2/tcpserver/appConfig.ts +0 -65
- package/src_working2/tcpserver/appmaster.ts +0 -522
- package/src_working2/validation/errors.ts +0 -6
- package/src_working2/webworkertesting/app.ts +0 -49
- package/src_working2/webworkertesting/worker.ts +0 -24
- package/src_working2/workerprocessbase.test.ts +0 -47
- package/src_working2/workerprocessbase.ts +0 -187
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import debugModule from 'debug'
|
|
3
|
-
const debug = debugModule(`proc:${process.pid}`);
|
|
4
|
-
|
|
5
|
-
import { $Options } from '@nsshunt/stsconfig'
|
|
6
|
-
const goptions = $Options()
|
|
7
|
-
|
|
8
|
-
import fs from "fs"
|
|
9
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10
|
-
import colors from 'colors'
|
|
11
|
-
|
|
12
|
-
import { createAdapter as clusterCreateAdapter } from '@socket.io/cluster-adapter'
|
|
13
|
-
import { createAdapter } from "@socket.io/redis-streams-adapter";
|
|
14
|
-
|
|
15
|
-
import { JSONObject, Sleep } from '@nsshunt/stsutils'
|
|
16
|
-
|
|
17
|
-
import { ProcessOptions, STSServerType } from './processoptions'
|
|
18
|
-
import { ProcessBase } from './processbase';
|
|
19
|
-
|
|
20
|
-
import { register, Counter, collectDefaultMetrics, AggregatorRegistry } from 'prom-client'
|
|
21
|
-
|
|
22
|
-
import { createServer as createServerHttps } from 'https'
|
|
23
|
-
import { createServer } from 'http'
|
|
24
|
-
import tls from 'node:tls'
|
|
25
|
-
import net from 'node:net'
|
|
26
|
-
|
|
27
|
-
import { Server, ServerOptions } from "socket.io";
|
|
28
|
-
import { STSExpressServer } from './server';
|
|
29
|
-
import { Express } from 'express'
|
|
30
|
-
|
|
31
|
-
import { createClient, RedisClientType } from 'redis';
|
|
32
|
-
|
|
33
|
-
import jayson from 'jayson'
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* todo
|
|
37
|
-
* @typedef {Object} options - todo
|
|
38
|
-
* @property {boolean} [wssServer=false] - Create a web socket server on this worker instance
|
|
39
|
-
*/
|
|
40
|
-
export class ServerProcessBase extends ProcessBase
|
|
41
|
-
{
|
|
42
|
-
#masterProcessExitTime = goptions.masterProcessExitTime;
|
|
43
|
-
#io: Server | null = null;
|
|
44
|
-
#redisClient: RedisClientType | null = null;
|
|
45
|
-
#httpServer: any = null;
|
|
46
|
-
#expressServer: STSExpressServer | null = null;
|
|
47
|
-
#sockets: net.Socket[] = [ ];
|
|
48
|
-
#shuttingDown = false;
|
|
49
|
-
|
|
50
|
-
constructor(options: ProcessOptions) {
|
|
51
|
-
super(options);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get httpServer() {
|
|
55
|
-
return this.#httpServer;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
get io() {
|
|
59
|
-
return this.#io;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
get expressServer(): STSExpressServer | null {
|
|
63
|
-
return this.#expressServer;
|
|
64
|
-
}
|
|
65
|
-
set expressServer(val: STSExpressServer | null) {
|
|
66
|
-
this.#expressServer = val;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Setup server to Prometheus scrapes:
|
|
70
|
-
#SetupPrometheusEndPoints = (expressServer: Express) => {
|
|
71
|
-
// AggregatorRegistry is required here in the worker as well as the master in order for prom-client to work correctly.
|
|
72
|
-
new AggregatorRegistry();
|
|
73
|
-
|
|
74
|
-
const prefix = 'sts_';
|
|
75
|
-
|
|
76
|
-
collectDefaultMetrics({
|
|
77
|
-
labels: { NODE_APP_INSTANCE: process.pid },
|
|
78
|
-
prefix: prefix
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
const c = new Counter({
|
|
82
|
-
name: 'sts_test_counter',
|
|
83
|
-
help: 'Example of a counter',
|
|
84
|
-
labelNames: ['code'],
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
setInterval(() => {
|
|
88
|
-
c.inc({ code: 200 });
|
|
89
|
-
}, 1000).unref();
|
|
90
|
-
|
|
91
|
-
setInterval(() => {
|
|
92
|
-
c.inc({ code: 400 });
|
|
93
|
-
c.inc({ code: 'worker_' + process.pid });
|
|
94
|
-
}, 500).unref();
|
|
95
|
-
|
|
96
|
-
expressServer.get('/metrics', async (req: any, res: any) => {
|
|
97
|
-
try {
|
|
98
|
-
res.set('Content-Type', register.contentType);
|
|
99
|
-
res.end(await register.metrics());
|
|
100
|
-
} catch (ex) {
|
|
101
|
-
res.status(500).end(ex);
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
expressServer.get('/metrics/counter', async (req: any, res: any) => {
|
|
106
|
-
try {
|
|
107
|
-
res.set('Content-Type', register.contentType);
|
|
108
|
-
res.end(await register.getSingleMetricAsString('test_counter'));
|
|
109
|
-
} catch (ex) {
|
|
110
|
-
res.status(500).end(ex);
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
#SetupTLSServer = async (socket: net.Socket): Promise<void> => {
|
|
116
|
-
// Add a 'close' event handler to this instance of socket
|
|
117
|
-
console.log('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort + ' ' + process.pid);
|
|
118
|
-
this.#sockets.push(socket);
|
|
119
|
-
|
|
120
|
-
//const self = this;
|
|
121
|
-
socket.on('close', (data: any) => {
|
|
122
|
-
const index = this.#sockets.findIndex(function(o) {
|
|
123
|
-
return o.remoteAddress === socket.remoteAddress && o.remotePort === socket.remotePort;
|
|
124
|
-
})
|
|
125
|
-
if (index !== -1) this.#sockets.splice(index, 1);
|
|
126
|
-
console.log('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort + ' ' + process.pid);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
socket.on('data', function(data: any) {
|
|
130
|
-
console.log('DATA ' + socket.remoteAddress + ': ' + socket.remotePort + ': ' + data);
|
|
131
|
-
socket.write(socket.remoteAddress + ':' + socket.remotePort + " said " + data + '\n');
|
|
132
|
-
|
|
133
|
-
// Write the data back to all the connected, the client will receive it as data from the server
|
|
134
|
-
/*
|
|
135
|
-
self.#sockets.forEach(function(socket, index, array) {
|
|
136
|
-
socket.write(socket.remoteAddress + ':' + socket.remotePort + " said " + data + '\n');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
*/
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
#SetupRPCServer = async (socket: net.Socket): Promise<void> => {
|
|
144
|
-
console.log('CONNECTED: ' + socket.remoteAddress + ':' + socket.remotePort + ' ' + process.pid);
|
|
145
|
-
|
|
146
|
-
socket.on('close', function(data: any) {
|
|
147
|
-
console.log('CLOSED: ' + socket.remoteAddress + ' ' + socket.remotePort + ' ' + process.pid);
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
socket.on('data', function(data: any) {
|
|
151
|
-
console.log('DATA ' + socket.remoteAddress + ': ' + data);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
#SetupWSSServer = async (): Promise<void> => {
|
|
156
|
-
// socket.io
|
|
157
|
-
// WebSocket
|
|
158
|
-
const options: Partial<ServerOptions> = {
|
|
159
|
-
transports: [ "websocket" ] // or [ "websocket", "polling" ] (to use long-poolling. Note that the order matters)
|
|
160
|
-
// The default path is /socket.io
|
|
161
|
-
// This can be changed with the path option as shown below
|
|
162
|
-
//,path: '/zzz'
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
//this.#io = require("socket.io")(this.#httpServer, options);
|
|
166
|
-
this.#io = new Server(this.#httpServer, options);
|
|
167
|
-
|
|
168
|
-
if (this.options.clusterMode) {
|
|
169
|
-
if (this.options.useRedisAdaptor) {
|
|
170
|
-
this.LogEx(`Using Redis for socket.io cluster management (worker)`);
|
|
171
|
-
if (this.options.redisAdaptorUrl) {
|
|
172
|
-
this.LogEx(`Redis url: [${this.options.redisAdaptorUrl}]`);
|
|
173
|
-
this.#redisClient = createClient({url: this.options.redisAdaptorUrl});
|
|
174
|
-
} else {
|
|
175
|
-
this.LogEx(`Redis url: [localhost]`);
|
|
176
|
-
this.#redisClient = createClient();
|
|
177
|
-
}
|
|
178
|
-
await this.#redisClient.connect();
|
|
179
|
-
this.#io.adapter(createAdapter(this.#redisClient) as any);
|
|
180
|
-
this.LogEx(`Redis successfully connected.`);
|
|
181
|
-
} else {
|
|
182
|
-
this.#io.adapter(clusterCreateAdapter() as any);
|
|
183
|
-
this.LogEx(`Using nodejs cluster mode for socket.io cluster management`);
|
|
184
|
-
}
|
|
185
|
-
} else {
|
|
186
|
-
this.LogEx(`Not using any adaptors for socket.io cluster management.}`);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// To use a seperate socket server, the code below can be applied.
|
|
190
|
-
// this.#io = require("socket.io")(options);
|
|
191
|
-
// this.#io.adapter(createAdapter());
|
|
192
|
-
// this.#io.listen(3006);
|
|
193
|
-
// LogEx(`socket.io init`);
|
|
194
|
-
|
|
195
|
-
this.#io.engine.on("connection_error", (err) => {
|
|
196
|
-
this.LogEx(err.req); // the request object
|
|
197
|
-
this.LogEx(err.code); // the error code, for example 1
|
|
198
|
-
this.LogEx(err.message); // the error message, for example "Session ID unknown"
|
|
199
|
-
this.LogEx(err.context); // some additional error context
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
#GetTLSOptions = (): JSONObject => {
|
|
204
|
-
return {
|
|
205
|
-
key: fs.readFileSync(this.options.httpsServerKeyPath),
|
|
206
|
-
cert: fs.readFileSync(this.options.httpsServerCertificatePath)
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
#SetupExpressServer = async (useTls: boolean): Promise<void> => {
|
|
211
|
-
if (useTls) {
|
|
212
|
-
this.#httpServer = createServerHttps(this.#GetTLSOptions(), (this.#expressServer as STSExpressServer).App);
|
|
213
|
-
} else {
|
|
214
|
-
this.#httpServer = createServer((this.#expressServer as STSExpressServer).App);
|
|
215
|
-
}
|
|
216
|
-
if (this.options.prometheusSupport === true) {
|
|
217
|
-
this.#SetupPrometheusEndPoints((this.#expressServer as STSExpressServer).App);
|
|
218
|
-
}
|
|
219
|
-
if (this.options.wssServer === true) {
|
|
220
|
-
await this.#SetupWSSServer();
|
|
221
|
-
}
|
|
222
|
-
// https://stackoverflow.com/questions/21342828/node-express-unix-domain-socket-permissions
|
|
223
|
-
//@@httpServer.listen('/tmp/stsrest01.sock').on('listening', () =>
|
|
224
|
-
//@@httpServer.listen('/var/run/sts/stsrest01.sock').on('listening', () =>
|
|
225
|
-
this.#httpServer.listen(this.options.listenPort, () => {
|
|
226
|
-
//@@chmodSync(this.options.port, 511);
|
|
227
|
-
}).on('listening', () =>
|
|
228
|
-
{
|
|
229
|
-
this.LogEx(`live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
#SetupTCPRawServer = async (): Promise<void> => {
|
|
234
|
-
// The second parameter is the automatic listener for the secureConnection event from the tls.Server class
|
|
235
|
-
this.#httpServer = tls.createServer(this.#GetTLSOptions(), this.#SetupTLSServer);
|
|
236
|
-
this.#httpServer.listen(this.options.listenPort, 'stscore.stsmda.org', () => {
|
|
237
|
-
console.log('TCP Server is running on port ' + this.options.listenPort + '.');
|
|
238
|
-
}).on('listening', () =>
|
|
239
|
-
{
|
|
240
|
-
this.LogEx(`TCP live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
#SetupJSONRPCServer = async (): Promise<void> => {
|
|
245
|
-
const jaysonServer = new jayson.server();
|
|
246
|
-
// Supported methods here - move somewhere else ...
|
|
247
|
-
jaysonServer.method("add", function(args: any, callback: any) {
|
|
248
|
-
callback(null, args[0] + args[1]);
|
|
249
|
-
});
|
|
250
|
-
this.#httpServer = jaysonServer.tls(this.#GetTLSOptions());
|
|
251
|
-
(this.#httpServer as tls.Server).on('secureConnection', this.#SetupRPCServer);
|
|
252
|
-
this.#httpServer.listen(this.options.listenPort, 'stscore.stsmda.org', () => {
|
|
253
|
-
console.log('JSON RPC 2.0 Server is running on port ' + this.options.listenPort + '.');
|
|
254
|
-
}).on('listening', () =>
|
|
255
|
-
{
|
|
256
|
-
this.LogEx(`JSON RPC 2.0 live on ${this.options.endpoint}:${this.options.listenPort}${this.options.apiRoot}`);
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
ProcessTerminating = async (): Promise<void> => {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
override get shuttingDown(): boolean {
|
|
265
|
-
return this.#shuttingDown;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Terminate in order;
|
|
269
|
-
// forked worker threads (send signal)
|
|
270
|
-
// De-Register service
|
|
271
|
-
// systeminformation observers
|
|
272
|
-
// instrument timers (gauge etc.)
|
|
273
|
-
// publisher
|
|
274
|
-
// terminate UI (if loaded)
|
|
275
|
-
Terminate = async (clusterPerformExit: boolean, signal?: any): Promise<void> => {
|
|
276
|
-
if (this.#shuttingDown === false) {
|
|
277
|
-
this.#shuttingDown = true;
|
|
278
|
-
|
|
279
|
-
await this.ProcessTerminate();
|
|
280
|
-
|
|
281
|
-
await this.ProcessTerminating();
|
|
282
|
-
|
|
283
|
-
if (!this.options.clusterMode) {
|
|
284
|
-
if (this.GetUIController() !== null)
|
|
285
|
-
{
|
|
286
|
-
this.LogEx('Destroy the user interface controller.');
|
|
287
|
-
this.GetUIController().DestroyUI();
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
if (signal) {
|
|
291
|
-
this.LogEx(this.GetSignalColour(signal)(`Main Process (singleprocess): ${process.pid} received signal: ${signal}`));
|
|
292
|
-
} else {
|
|
293
|
-
this.LogEx(this.GetSignalColour(null)(`Main Process (singleprocess): ${process.pid} received Terminate without signal.`));
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
if (this.options.wssServer === true && this.#io !== null)
|
|
298
|
-
{
|
|
299
|
-
this.LogEx(`Disconnect Sockets.`);
|
|
300
|
-
if (this.socketIoServerHelper !== null) {
|
|
301
|
-
this.socketIoServerHelper.DisconnectSockets();
|
|
302
|
-
} else {
|
|
303
|
-
this.#io.disconnectSockets();
|
|
304
|
-
}
|
|
305
|
-
this.socketIoServerHelper = null;
|
|
306
|
-
this.#io = null;
|
|
307
|
-
// Note that this.#redisClient.disconnect() is not required becuase DisconnectSockets performs this action.
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
if (this.#httpServer) {
|
|
311
|
-
if (this.options.serverType === STSServerType.TCPRAW_TLS) {
|
|
312
|
-
this.#sockets.forEach((socket: net.Socket, index, array) => {
|
|
313
|
-
this.LogEx(`TCP Socket destroy, remote address: [${socket.remoteAddress}], remote port: [${socket.remotePort}]`.yellow);
|
|
314
|
-
socket.destroy();
|
|
315
|
-
//socket.end();
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
this.LogEx(`Closing httpServer.`);
|
|
319
|
-
await this.#httpServer.close();
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
if (this.options.useDatabase) {
|
|
323
|
-
this.LogEx(`Ending database connections and pools.`);
|
|
324
|
-
await this.TerminateDatabase();
|
|
325
|
-
//await this.accessLayer.enddatabase();
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (this.options.clusterMode) {
|
|
329
|
-
this.LogEx(`Performing exit value: [${clusterPerformExit}]`);
|
|
330
|
-
if (clusterPerformExit) {
|
|
331
|
-
this.LogEx(`Process will self terminate with process.exit(0).`);
|
|
332
|
-
} else {
|
|
333
|
-
this.LogEx(`Child process will not self terminate. Terminate will be handled by master process.`);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
//if (this.InstrumentController && this.InstrumentController.Workers.length > 0) {
|
|
338
|
-
if (this.InstrumentController) {
|
|
339
|
-
this.LogEx(`Ending publisher.`);
|
|
340
|
-
setTimeout(() => {
|
|
341
|
-
//if (this.InstrumentController && this.InstrumentController.Workers.length > 0) {
|
|
342
|
-
if (this.InstrumentController) {
|
|
343
|
-
this.InstrumentController.InstrumentTerminate();
|
|
344
|
-
}
|
|
345
|
-
}, 100);
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
//@@ always return here appears to always cleanly exit
|
|
349
|
-
// and cleanly exit from socket.io cluster adaptor
|
|
350
|
-
// without return here, socket.io cluster adaptor terminates in an error state
|
|
351
|
-
// as the implementation relies on cluster.on to send messages to worker threads
|
|
352
|
-
// but these have already been closed from the process.exit(0) below.
|
|
353
|
-
|
|
354
|
-
await Sleep(1000); // Allow socket.io time to clean-up
|
|
355
|
-
|
|
356
|
-
if (this.options.clusterMode) {
|
|
357
|
-
if (clusterPerformExit) {
|
|
358
|
-
setTimeout(() => {
|
|
359
|
-
process.exit(0);
|
|
360
|
-
}, 0);
|
|
361
|
-
}
|
|
362
|
-
} else {
|
|
363
|
-
if (this.options.processExitOnTerminate && this.options.processExitOnTerminate === true) {
|
|
364
|
-
setTimeout(() => {
|
|
365
|
-
this.LogEx(`Performing process.exit(0).`);
|
|
366
|
-
process.exit(0);
|
|
367
|
-
}, this.#masterProcessExitTime); // Give the workers time to terminate gracefully
|
|
368
|
-
} else {
|
|
369
|
-
this.LogEx(`Performing process.exit(0) - Immediate.`);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
} else {
|
|
373
|
-
this.LogEx(`Process already terminating.`);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
SetupSTSServer = async(): Promise<void> => {
|
|
378
|
-
switch (this.options.serverType) {
|
|
379
|
-
case STSServerType.EXPRESS :
|
|
380
|
-
await this.#SetupExpressServer(false);
|
|
381
|
-
break;
|
|
382
|
-
case STSServerType.EXPRESS_TLS :
|
|
383
|
-
await this.#SetupExpressServer(true);
|
|
384
|
-
break;
|
|
385
|
-
case STSServerType.TCPRAW_TLS :
|
|
386
|
-
await this.#SetupTCPRawServer();
|
|
387
|
-
break;
|
|
388
|
-
case STSServerType.JSONRPC2_TLS :
|
|
389
|
-
await this.#SetupJSONRPCServer();
|
|
390
|
-
break;
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF
|
|
2
|
-
import { $Options } from '@nsshunt/stsconfig'
|
|
3
|
-
const goptions = $Options()
|
|
4
|
-
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
|
|
7
|
-
import { Gauge, GaugeTypes, InstrumentGaugeOptions, InstrumentGaugeTelemetry } from '@nsshunt/stsinstrumentation'
|
|
8
|
-
|
|
9
|
-
import { ProcessOptions } from './processoptions'
|
|
10
|
-
import { ISingleProcessBase } from './commonTypes';
|
|
11
|
-
import { InstrumentDefinitions } from '@nsshunt/stspublisherserver'
|
|
12
|
-
import { STSExpressServer } from './server'
|
|
13
|
-
import { ServerProcessBase } from './serverprocessbase'
|
|
14
|
-
|
|
15
|
-
import si from 'systeminformation' // https://systeminformation.io/
|
|
16
|
-
|
|
17
|
-
export type EventCb = (socket: any, data: any) => void
|
|
18
|
-
|
|
19
|
-
export class SingleProcessBase extends ServerProcessBase implements ISingleProcessBase
|
|
20
|
-
{
|
|
21
|
-
/**
|
|
22
|
-
*
|
|
23
|
-
* @param {SingleProcessBaseOptions} options
|
|
24
|
-
*/
|
|
25
|
-
constructor(options: ProcessOptions) {
|
|
26
|
-
super(options)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
override CollectAdditionalTelemetry(): void {
|
|
30
|
-
const siValueObject = {
|
|
31
|
-
currentLoad: 'currentLoad'
|
|
32
|
-
}
|
|
33
|
-
si.get(siValueObject).then(data => {
|
|
34
|
-
this.UpdateInstrument(Gauge.CPU_SYSTEM_LOAD_GAUGE, {
|
|
35
|
-
val: data.currentLoad.currentLoad
|
|
36
|
-
} as InstrumentGaugeTelemetry);
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
override GetAdditionalInstruments(): InstrumentDefinitions {
|
|
41
|
-
return [
|
|
42
|
-
[ Gauge.CPU_SYSTEM_LOAD_GAUGE, GaugeTypes.INSTRUMENT_GAUGE, {
|
|
43
|
-
interval: goptions.instrumentationObservationInterval,
|
|
44
|
-
sampleSize: goptions.instrumentationTimeWindow
|
|
45
|
-
} as InstrumentGaugeOptions]
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* UIController (instance of UIController) to manage a console based user interface associated for this node application.
|
|
51
|
-
* @returns UIController instance to manage a console based user interface associated for this node application. Null for no capability.
|
|
52
|
-
*/
|
|
53
|
-
override GetUIController(): any {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
ProcessStarted() {
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
SetupServer(): Promise<boolean>
|
|
62
|
-
{
|
|
63
|
-
return new Promise((resolve, reject) => {
|
|
64
|
-
try {
|
|
65
|
-
this.SetupInstrumentation();
|
|
66
|
-
setTimeout(async () => {
|
|
67
|
-
try {
|
|
68
|
-
await this.SetupServerEx();
|
|
69
|
-
resolve(true);
|
|
70
|
-
} catch (error) {
|
|
71
|
-
reject(error);
|
|
72
|
-
}
|
|
73
|
-
}, 100);
|
|
74
|
-
} catch (error) {
|
|
75
|
-
reject(error);
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
SetupServerEx = async () => {
|
|
81
|
-
this.ProcessStartup();
|
|
82
|
-
|
|
83
|
-
if (this.options.expressServerRouteFactory || this.options.expressServerRouteStaticFactory) {
|
|
84
|
-
this.expressServer = new STSExpressServer(this.options, this);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
this.LogEx(`Service instance starting. Instance Id: [${this.options.serviceInstanceId}]`);
|
|
88
|
-
this.LogEx(`Master process:${process.pid} started`);
|
|
89
|
-
|
|
90
|
-
this.LogSystemTelemetry();
|
|
91
|
-
|
|
92
|
-
process.on('SIGINT', async () => {
|
|
93
|
-
await this.Terminate(false, 'SIGINT');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
process.on('SIGTERM', async () => {
|
|
97
|
-
await this.Terminate(false, 'SIGTERM');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
process.on('exit', (code) => {
|
|
101
|
-
if (code === 0) {
|
|
102
|
-
this.LogEx(chalk.green(`Main Process: ${process.pid} terminated gracefully with code: ${code}`));
|
|
103
|
-
} else {
|
|
104
|
-
this.LogEx(chalk.red(`Main Process: ${process.pid} terminated with code: ${code}`));
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
await this.SetupSTSServer();
|
|
109
|
-
|
|
110
|
-
this.ProcessStarted();
|
|
111
|
-
|
|
112
|
-
this.LogEx(chalk.green(`Main process:${process.pid} started`));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async TerminateApplication()
|
|
116
|
-
{
|
|
117
|
-
await this.Terminate(false, 'SIGINT');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
override ProcessTerminating = async (): Promise<void> => {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
|
|
2
|
-
import Debug from "debug";
|
|
3
|
-
const debug = Debug(`proc:${process.pid}:socketiohelper`);
|
|
4
|
-
|
|
5
|
-
import { JSONObject } from '@nsshunt/stsutils'
|
|
6
|
-
|
|
7
|
-
import { Server, Namespace, Socket } from "socket.io";
|
|
8
|
-
|
|
9
|
-
import { STSSocketIONamespace, STSServerSocket, STSNamespace,
|
|
10
|
-
ISocketIoServerHelper, ServerEventCb, InterServerEvents } from './commonTypes'
|
|
11
|
-
|
|
12
|
-
import { STSDefaultClientToServerEvents, STSDefaultServerToClientEvents } from '@nsshunt/stssocketio-client'
|
|
13
|
-
|
|
14
|
-
export interface ISocketIoServerHelperOptions
|
|
15
|
-
{
|
|
16
|
-
logger: (message: string) => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class SocketIoServerHelper<ClientToServerEvents extends STSDefaultClientToServerEvents, ServerToClientEvents extends STSDefaultServerToClientEvents> implements ISocketIoServerHelper<ClientToServerEvents, ServerToClientEvents>
|
|
20
|
-
{
|
|
21
|
-
#socketIoServerHelperOptions: ISocketIoServerHelperOptions
|
|
22
|
-
|
|
23
|
-
constructor(options: ISocketIoServerHelperOptions) { // IProcessBase
|
|
24
|
-
this.#socketIoServerHelperOptions = options;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
#namespace: Record<string, STSSocketIONamespace> = { };
|
|
28
|
-
|
|
29
|
-
LogMessage = (namespace: STSSocketIONamespace, message: string): void => {
|
|
30
|
-
|
|
31
|
-
this.#socketIoServerHelperOptions.logger(`${namespace.namespace}: ${message}`);
|
|
32
|
-
/*
|
|
33
|
-
this.#stsApp.UpdateInstrument(Gauge.LOGGER, {
|
|
34
|
-
LogMessage: message
|
|
35
|
-
} as InstrumentLogTelemetry);
|
|
36
|
-
*/
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
LeaveRoom = (namespace: STSSocketIONamespace, socket: Socket<ClientToServerEvents, ServerToClientEvents>, room: string): void => {
|
|
40
|
-
const logMessage = `${namespace.socketionamespace.name}: Leaving room [${room}]`;
|
|
41
|
-
debug(logMessage);
|
|
42
|
-
this.LogMessage(namespace, logMessage);
|
|
43
|
-
socket.leave(room);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
JoinRoom = (namespace: STSSocketIONamespace, socket: Socket<ClientToServerEvents, ServerToClientEvents>, room: string): void => {
|
|
47
|
-
const logMessage = `${namespace.socketionamespace.name}: Socket joining room [${room}], ID: [${socket.id}]`;
|
|
48
|
-
debug(logMessage);
|
|
49
|
-
this.LogMessage(namespace, logMessage);
|
|
50
|
-
socket.join(room);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
#SetupStandardEvents = (namespace: STSSocketIONamespace, socket: Socket<STSDefaultClientToServerEvents, STSDefaultServerToClientEvents>): void => {
|
|
54
|
-
socket.on("__STSdisconnect", (reason) => {
|
|
55
|
-
debug(`${namespace.socketionamespace.name}: socket disconnect, ID: [${socket.id}] [${reason}]`);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
socket.on("__STSdisconnecting", (reason, callBackResult) => {
|
|
59
|
-
debug(`${namespace.socketionamespace.name}: socket disconnecting, ID: [${socket.id}] [${reason}]`);
|
|
60
|
-
callBackResult("__STSdisconnecting accepted by server.");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
socket.on('__STSjoinRoom', (rooms: string[]): void => { //@@ names
|
|
64
|
-
rooms.forEach((room) => {
|
|
65
|
-
const logMessage = `${namespace.socketionamespace.name}:socket.on:joinRoom: Socket joining room [${room}], ID: [${socket.id}]`;
|
|
66
|
-
debug(logMessage);
|
|
67
|
-
this.JoinRoom(namespace, socket, room)
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
socket.on('__STSleaveRoom', (rooms: string[]): void => { //@@ names
|
|
72
|
-
rooms.forEach((room) => {
|
|
73
|
-
const logMessage = `${namespace.socketionamespace.name}:socket.on:joinRoom: Socket leaving room [${room}], ID: [${socket.id}]`;
|
|
74
|
-
debug(logMessage);
|
|
75
|
-
this.LeaveRoom(namespace, socket, room);
|
|
76
|
-
});
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
socket.on('__STSsendToRoom', (rooms: string[], payload: { command: string, payload: JSONObject }): void => {
|
|
80
|
-
rooms.forEach((room) => {
|
|
81
|
-
const logMessage = `${namespace.socketionamespace.name}:socket.on:sendToRoom: Sending to room [${room}], ID: [${socket.id}]`;
|
|
82
|
-
debug(logMessage);
|
|
83
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
-
namespace.socketionamespace.to(room).emit(payload.command as any, payload);
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Use this middleward to check every incomming connection
|
|
90
|
-
#SetupConnectionMiddleware = (nameSpace: STSSocketIONamespace) => {
|
|
91
|
-
nameSpace.socketionamespace.use((socket, next) => {
|
|
92
|
-
//console.log(JSON.stringify(socket));
|
|
93
|
-
//console.log(JSON.stringify(socket.handshake.auth));
|
|
94
|
-
//console.log(JSON.stringify(socket.handshake.headers));
|
|
95
|
-
//if (isValid(socket.request)) {
|
|
96
|
-
const a=5; // for lint purposes
|
|
97
|
-
if (a === 5) {
|
|
98
|
-
next();
|
|
99
|
-
} else {
|
|
100
|
-
next(new Error("invalid"));
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Use this middleware to check very packet being received
|
|
106
|
-
#SetupMessageMiddleware = (socket: STSServerSocket) => {
|
|
107
|
-
socket.use(([event, ...args], next) => {
|
|
108
|
-
//console.log(JSON.stringify(event));
|
|
109
|
-
//console.log(JSON.stringify(args));
|
|
110
|
-
/*
|
|
111
|
-
if (isUnauthorized(event)) {
|
|
112
|
-
return next(new Error("unauthorized event"));
|
|
113
|
-
}
|
|
114
|
-
*/
|
|
115
|
-
next();
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
SetupNamespace = (io: Server, namespace: STSNamespace, rooms: string[], autoJoinRooms: boolean, /* serverSocketEvents: ServerSocketEvent[], */
|
|
120
|
-
socketConnectCallBack: ((socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents>) => void) | null,
|
|
121
|
-
socketEventsCallBack: ((socket: Socket<ClientToServerEvents, ServerToClientEvents, InterServerEvents>) => void) | null
|
|
122
|
-
): Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents> => {
|
|
123
|
-
// Create STS Command Centre Client namespace
|
|
124
|
-
this.#namespace[namespace] = {
|
|
125
|
-
namespace: namespace,
|
|
126
|
-
pid: process.pid,
|
|
127
|
-
socketionamespace: io.of(`/${namespace}/`)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
this.#SetupConnectionMiddleware(this.#namespace[namespace]);
|
|
131
|
-
|
|
132
|
-
this.#namespace[namespace].socketionamespace.on("connection", socket => {
|
|
133
|
-
const logMessage = `${namespace}: Socket connected, ID: [${socket.id}]`;
|
|
134
|
-
debug(logMessage);
|
|
135
|
-
this.LogMessage(this.#namespace[namespace], logMessage);
|
|
136
|
-
debug(`${namespace}: Auth: [${JSON.stringify(socket.handshake.auth)}]`);
|
|
137
|
-
|
|
138
|
-
this.#SetupMessageMiddleware(socket);
|
|
139
|
-
|
|
140
|
-
if (autoJoinRooms) {
|
|
141
|
-
rooms.map((room) => {
|
|
142
|
-
this.JoinRoom(this.#namespace[namespace], socket, room);
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
this.#SetupStandardEvents(this.#namespace[namespace], socket);
|
|
147
|
-
|
|
148
|
-
if (socketConnectCallBack) {
|
|
149
|
-
setTimeout(() => {
|
|
150
|
-
socketConnectCallBack(socket);
|
|
151
|
-
}, 0);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (socketEventsCallBack) {
|
|
155
|
-
socketEventsCallBack(socket);
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return this.#namespace[namespace].socketionamespace as Namespace<ClientToServerEvents, ServerToClientEvents, InterServerEvents>;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
GetSTSSocketIONamespace = (namespace: string): STSSocketIONamespace => {
|
|
163
|
-
return this.#namespace[namespace];
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
DisconnectSockets = (): void =>
|
|
167
|
-
{
|
|
168
|
-
for (const [, namespace] of Object.entries(this.#namespace)) {
|
|
169
|
-
namespace.socketionamespace.disconnectSockets();
|
|
170
|
-
}
|
|
171
|
-
this.#namespace = { };
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
SetupEvent(event: ClientToServerEvents, eventCb: ServerEventCb): ISocketIoServerHelper<ClientToServerEvents, ServerToClientEvents> {
|
|
175
|
-
return this as any;
|
|
176
|
-
}
|
|
177
|
-
}
|