iosignal 3.1.0 → 3.3.0
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/README.ko.md +1 -1
- package/README.md +1 -225
- package/dist/io.d.ts +5 -3
- package/dist/io.js +4 -4
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +4 -4
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +285 -182
- package/dist/types/client/IOCore.d.ts +5 -3
- package/examples/react-chat-js/dist/assets/index-e2KOTYW8.js +65 -0
- package/examples/react-chat-js/dist/index.html +1 -1
- package/examples/react-chat-js/package-lock.json +1 -1
- package/examples/server/index.js +62 -9
- package/examples/server/package-lock.json +833 -2
- package/examples/server/package.json +1 -0
- package/examples/server/public/index.html +26 -0
- package/examples/svelte-chat-js/package-lock.json +11 -95
- package/examples/svelte-chat-js/package.json +1 -0
- package/examples/svelte-chat-js/src/app.html +1 -0
- package/examples/svelte-chat-js/src/routes/+layout.svelte +0 -4
- package/examples/svelte-chat-js/src/routes/+page.svelte +5 -0
- package/examples/svelte-chat-js/svelte.config.js +10 -2
- package/index.js +2 -1
- package/package.json +1 -1
- package/src/api/RedisAPI.js +19 -31
- package/src/api/api_reply.js +14 -6
- package/src/api/api_sudo.js +2 -8
- package/src/auth/Auth_Redis.js +8 -3
- package/src/auth/BohoAuth.js +12 -12
- package/src/client/CongPacket.js +2 -0
- package/src/client/IOCore.js +28 -12
- package/src/server/Manager.js +18 -3
- package/src/server/Metric.js +1 -2
- package/src/server/Remote.js +5 -0
- package/src/server/RemoteCore.js +27 -34
- package/src/server/Server.js +139 -66
- package/src/server/serverOption.js +5 -4
- package/test-nodejs/client-playToggle.js +19 -0
|
@@ -19,6 +19,11 @@
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
if (browser) {
|
|
22
|
+
let wsURL = new URL( document.URL )
|
|
23
|
+
wsURL.protocol = 'ws'
|
|
24
|
+
console.log( 'ws url:', wsURL.href)
|
|
25
|
+
|
|
26
|
+
// io = new IO(wsURL.href);
|
|
22
27
|
io = new IO(url);
|
|
23
28
|
if (dev)
|
|
24
29
|
console.log("new io:", IO.version, IO.instanceCount, IO.webSocketCount);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import adapter from '@sveltejs/adapter-
|
|
1
|
+
import adapter from '@sveltejs/adapter-static';
|
|
2
2
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
|
3
3
|
|
|
4
4
|
/** @type {import('@sveltejs/kit').Config} */
|
|
@@ -7,7 +7,15 @@ const config = {
|
|
|
7
7
|
runes: true
|
|
8
8
|
},
|
|
9
9
|
kit: {
|
|
10
|
-
|
|
10
|
+
adapter: adapter({
|
|
11
|
+
// default options are shown. On some platforms
|
|
12
|
+
// these options are set automatically — see below
|
|
13
|
+
pages: 'build',
|
|
14
|
+
assets: 'build',
|
|
15
|
+
// fallback: 'index.html',
|
|
16
|
+
precompress: false,
|
|
17
|
+
strict: true
|
|
18
|
+
})
|
|
11
19
|
},
|
|
12
20
|
preprocess: vitePreprocess()
|
|
13
21
|
};
|
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import pkg from './package.json' with { type: 'json' };
|
|
2
|
+
export const version = pkg.version;
|
|
2
3
|
export { IOCongSocket } from './src/client/IOCongSocket.js'
|
|
3
4
|
export { IOWS as IO } from './src/client/IOWS.js'
|
|
4
5
|
export { pack, CongRx } from './src/client/CongPacket.js'
|
package/package.json
CHANGED
package/src/api/RedisAPI.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RedisAPI <IOSignal API>
|
|
3
|
+
*
|
|
4
|
+
* iosignal 클라이언트의 redis 질의 요청을 받으면,
|
|
5
|
+
* redisClient 로 연결된 redis-server 에게 질의 후 결과를 되돌려 준다.
|
|
6
|
+
*
|
|
7
|
+
* client ex:
|
|
8
|
+
* await io.req('redis','hget','user:id' )
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
1
11
|
import { STATUS } from './api_constant.js'
|
|
2
12
|
|
|
3
13
|
const MIN_LEVEL = 200;
|
|
4
14
|
const COMMANDS = [
|
|
5
|
-
'GET', 'SET',
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'EXISTS', 'SREM',
|
|
10
|
-
'DEL', 'KEYS',
|
|
11
|
-
'SAVE'
|
|
15
|
+
'GET', 'SET', 'HGETALL', 'HGET', 'HSET', 'SADD', 'SISMEMBER',
|
|
16
|
+
'SMEMBERS', 'EXISTS', 'SREM', 'DEL', 'KEYS', 'SAVE',
|
|
17
|
+
'get', 'set', 'hGetAll', 'hGet', 'hSet', 'sAdd', 'sIsMember',
|
|
18
|
+
'sMembers', 'exists', 'sRem', 'del', 'keys', 'save'
|
|
12
19
|
]
|
|
13
20
|
|
|
14
21
|
export class RedisAPI {
|
|
@@ -21,42 +28,23 @@ export class RedisAPI {
|
|
|
21
28
|
this.commands = COMMANDS
|
|
22
29
|
}
|
|
23
30
|
|
|
24
|
-
|
|
25
31
|
checkPermission(remote, req) {
|
|
26
|
-
|
|
27
|
-
if (remote.level >= this.minLevel) {
|
|
28
|
-
return true
|
|
29
|
-
} else {
|
|
30
|
-
return false
|
|
31
|
-
}
|
|
32
|
+
return (remote.level >= this.minLevel) ? true : false;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
35
|
async request(remote, req) {
|
|
36
|
-
|
|
37
36
|
let result;
|
|
38
|
-
let status = STATUS.OK;
|
|
39
37
|
try {
|
|
40
38
|
let cmd = req.topic
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
console.log('RedisAPI call:', cmd, req.args)
|
|
44
|
-
|
|
45
|
-
if (req.args.length > 0) {
|
|
46
|
-
result = await this.redisClient[cmd](...req.args)
|
|
47
|
-
} else {
|
|
48
|
-
result = await this.redisClient[cmd]()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
if (req.args?.length > 0) {
|
|
40
|
+
result = await this.redisClient[cmd](...req.args)
|
|
52
41
|
} else {
|
|
53
|
-
|
|
42
|
+
result = await this.redisClient[cmd]()
|
|
54
43
|
}
|
|
55
|
-
remote.response(req.mid,
|
|
44
|
+
remote.response(req.mid, STATUS.OK, result)
|
|
56
45
|
} catch (e) {
|
|
57
46
|
remote.response(req.mid, STATUS.ERROR, e.message)
|
|
58
47
|
}
|
|
59
|
-
|
|
60
48
|
}
|
|
61
49
|
|
|
62
50
|
}
|
package/src/api/api_reply.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
|
|
2
|
+
/**
|
|
3
|
+
* simple IOSignal API example.
|
|
4
|
+
*/
|
|
2
5
|
|
|
3
6
|
import { STATUS } from './api_constant.js'
|
|
7
|
+
export const commands = ['echo', 'date', 'unixtime'];
|
|
4
8
|
|
|
5
9
|
const MIN_LEVEL = 0;
|
|
6
|
-
|
|
7
10
|
export function checkPermission(remote) {
|
|
8
|
-
|
|
9
|
-
return true
|
|
10
|
-
} else {
|
|
11
|
-
return false
|
|
12
|
-
}
|
|
11
|
+
return (remote.level >= MIN_LEVEL) ? true : false;
|
|
13
12
|
}
|
|
14
13
|
|
|
14
|
+
/**
|
|
15
|
+
* client api call example: await io.req('reply','echo','hello')
|
|
16
|
+
*/
|
|
15
17
|
export async function echo(remote, req) {
|
|
16
18
|
if (!req.args)
|
|
17
19
|
remote.response(req.mid, STATUS.ERROR, 'no message to echo')
|
|
@@ -19,11 +21,17 @@ export async function echo(remote, req) {
|
|
|
19
21
|
remote.response(req.mid, STATUS.OK, req.args)
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
/**
|
|
25
|
+
* client api call example: await io.req('reply','date')
|
|
26
|
+
*/
|
|
22
27
|
export async function date(remote, req) {
|
|
23
28
|
let r = new Date().toUTCString()
|
|
24
29
|
remote.response(req.mid, STATUS.OK, r)
|
|
25
30
|
}
|
|
26
31
|
|
|
32
|
+
/**
|
|
33
|
+
* client api call example: await io.req('reply','unixtime')
|
|
34
|
+
*/
|
|
27
35
|
export async function unixtime(remote, req) {
|
|
28
36
|
let r = Math.floor(Date.now() / 1000)
|
|
29
37
|
remote.response(req.mid, STATUS.OK, r)
|
package/src/api/api_sudo.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { STATUS } from './api_constant.js'
|
|
2
2
|
|
|
3
|
-
const MIN_LEVEL = 255;
|
|
4
|
-
|
|
5
3
|
export const commands = [
|
|
6
4
|
'cid', 'remotes', 'clients',
|
|
7
5
|
'channels', 'subscribers',
|
|
@@ -11,13 +9,9 @@ export const commands = [
|
|
|
11
9
|
'adddevice', 'getdevice', 'deldevice'
|
|
12
10
|
]
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
const MIN_LEVEL = 255;
|
|
15
13
|
export function checkPermission(remote) {
|
|
16
|
-
|
|
17
|
-
return true
|
|
18
|
-
} else {
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
14
|
+
return (remote.level >= MIN_LEVEL) ? true : false;
|
|
21
15
|
}
|
|
22
16
|
|
|
23
17
|
export async function request(remote, req) {
|
package/src/auth/Auth_Redis.js
CHANGED
|
@@ -13,11 +13,15 @@ export class Auth_Redis extends BohoAuth {
|
|
|
13
13
|
|
|
14
14
|
// get device key from DB. (for Boho auth.)
|
|
15
15
|
async getAuth(id) {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
try {
|
|
17
|
+
let result = await this.redis.hGetAll(DEVICE_PREFIX + id)
|
|
18
|
+
if (result.key) return result
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.log('getAuth', error)
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
//api_sudo call
|
|
21
25
|
async getAuthIdList() {
|
|
22
26
|
let result = await this.redis.keys(DEVICE_PREFIX + '*')
|
|
23
27
|
result = result.map(v => {
|
|
@@ -32,6 +36,7 @@ export class Auth_Redis extends BohoAuth {
|
|
|
32
36
|
return this.redis.hSet(DEVICE_PREFIX + id, { 'key': Base64hashKey, 'cid': cid, 'level': level })
|
|
33
37
|
}
|
|
34
38
|
|
|
39
|
+
//api_sudo call
|
|
35
40
|
async delAuth(id) {
|
|
36
41
|
return this.redis.del(DEVICE_PREFIX + id)
|
|
37
42
|
}
|
package/src/auth/BohoAuth.js
CHANGED
|
@@ -20,10 +20,9 @@ export class BohoAuth {
|
|
|
20
20
|
let peerInfo = `FAIL #${peer.ssid} reason:${reason} `
|
|
21
21
|
this.authLogger.log(peerInfo)
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
console.log('## AUTH_FAIL reason:', reason)
|
|
25
|
-
// peer.send( Buffer.from( [Boho.BohoMsg.AUTH_FAIL] ))
|
|
23
|
+
// console.log('##### AUTH_FAIL reason: ', reason)
|
|
26
24
|
peer.setState(CLIENT_STATE.AUTH_FAIL)
|
|
25
|
+
// add some delay time.
|
|
27
26
|
setTimeout(e => {
|
|
28
27
|
peer.send(Buffer.from([Boho.BohoMsg.AUTH_FAIL]))
|
|
29
28
|
}, serverOption.auth.delay_auth_fail)
|
|
@@ -33,30 +32,31 @@ export class BohoAuth {
|
|
|
33
32
|
try {
|
|
34
33
|
//1. unpack
|
|
35
34
|
let infoPack = MBP.unpack(auth_hmac, Boho.Meta.AUTH_HMAC)
|
|
35
|
+
|
|
36
36
|
if (!infoPack) {
|
|
37
37
|
this.send_auth_fail(peer, 'unpack auth_pack fail');
|
|
38
38
|
return
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
let id = ""
|
|
42
42
|
if (infoPack.id8.includes(0)) {
|
|
43
43
|
id = decoder.decode(infoPack.id8.subarray(0, infoPack.id8.indexOf(0)));
|
|
44
44
|
} else {
|
|
45
45
|
id = decoder.decode(infoPack.id8);
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
//2. get key of id from DB
|
|
49
49
|
let authInfo = await this.getAuth(id)
|
|
50
50
|
|
|
51
|
-
// console.log('##### authInfo',authInfo )
|
|
52
|
-
if (serverOption.debug.showAuthInfo) {
|
|
53
|
-
}
|
|
54
|
-
|
|
55
51
|
if (!authInfo) {
|
|
56
52
|
this.send_auth_fail(peer, 'NO ID:' + id);
|
|
57
53
|
return
|
|
58
54
|
}
|
|
59
55
|
|
|
56
|
+
if (serverOption.debug.showAuthInfo) {
|
|
57
|
+
console.log('[debug]showAuthInfo',authInfo )
|
|
58
|
+
}
|
|
59
|
+
|
|
60
60
|
// console.log('db authInfo.key: ', authInfo.key)
|
|
61
61
|
peer.boho.copy_id8(infoPack.id8)
|
|
62
62
|
// type of key
|
|
@@ -107,6 +107,7 @@ export class BohoAuth {
|
|
|
107
107
|
|
|
108
108
|
//6. delete current (temp rand)cid if exist.
|
|
109
109
|
if (peer.cid) {
|
|
110
|
+
console.log('duplicate cid')
|
|
110
111
|
peer.manager.cid2remote.delete(peer.cid)
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -114,6 +115,7 @@ export class BohoAuth {
|
|
|
114
115
|
peer.did = id
|
|
115
116
|
peer.cid = authInfo.cid
|
|
116
117
|
peer.nick = authInfo.cid // temporary: nick as cid
|
|
118
|
+
if( authInfo.uid ) peer.uid = authInfo.uid
|
|
117
119
|
|
|
118
120
|
//8. setting quota level.
|
|
119
121
|
let quotaLevel = serverOption.defaultQuotaIndex;
|
|
@@ -152,13 +154,11 @@ export class BohoAuth {
|
|
|
152
154
|
}
|
|
153
155
|
return authInfo
|
|
154
156
|
} catch (error) {
|
|
155
|
-
this.send_auth_fail(peer, 'caught: unknown error' + error);
|
|
157
|
+
this.send_auth_fail(peer, '[BohoAuth]caught: unknown error:' + error);
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
|
|
163
163
|
}
|
|
164
164
|
|
package/src/client/CongPacket.js
CHANGED
|
@@ -11,6 +11,8 @@ export const CongType = {
|
|
|
11
11
|
// support LittleEndian system.
|
|
12
12
|
export function pack(payload) {
|
|
13
13
|
|
|
14
|
+
if( payload.byteLength == undefined ) payload = Buffer.from(payload)
|
|
15
|
+
|
|
14
16
|
if (payload.byteLength < 256) { //one byte len
|
|
15
17
|
return MBP.pack(
|
|
16
18
|
MBP.MB('#type', '8', CongType.TYPE_LEN1),
|
package/src/client/IOCore.js
CHANGED
|
@@ -207,7 +207,7 @@ export class IOCore extends EventEmitter {
|
|
|
207
207
|
close() {
|
|
208
208
|
if (this._closed) return;
|
|
209
209
|
this._closed = true;
|
|
210
|
-
|
|
210
|
+
// console.log('####### IOCOre.js close() called')
|
|
211
211
|
// If auto-reconnect is disabled, we must stop the keep-alive timer.
|
|
212
212
|
if (this.autoReconnect === false) {
|
|
213
213
|
clearInterval(this.connectionCheckerIntervalID);
|
|
@@ -430,13 +430,26 @@ export class IOCore extends EventEmitter {
|
|
|
430
430
|
case IOMsg.PONG:
|
|
431
431
|
break;
|
|
432
432
|
|
|
433
|
+
case IOMsg.ECHO:
|
|
434
|
+
try {
|
|
435
|
+
let str = decoder.decode(buffer.subarray(1))
|
|
436
|
+
|
|
437
|
+
this.emit('echo', str)
|
|
438
|
+
} catch (error) {
|
|
439
|
+
this.emit('error', new Error('ECHO data error'))
|
|
440
|
+
}
|
|
441
|
+
break;
|
|
442
|
+
|
|
433
443
|
case IOMsg.IAM_RES:
|
|
434
444
|
try {
|
|
435
445
|
let str = decoder.decode(buffer.subarray(1))
|
|
436
446
|
let jsonInfo = JSON.parse(str)
|
|
437
|
-
if (jsonInfo.ip) {
|
|
438
|
-
|
|
439
|
-
}
|
|
447
|
+
if (jsonInfo.ip) { this.ip = jsonInfo.ip; }
|
|
448
|
+
if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
|
|
449
|
+
if (jsonInfo.did) { this.did = jsonInfo.did; }
|
|
450
|
+
if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
|
|
451
|
+
// TIP. cid from [CID_RES], level from [QUOTA_LEVEL]
|
|
452
|
+
this.emit('iam_res', str )
|
|
440
453
|
} catch (error) {
|
|
441
454
|
this.emit('error', new Error('IAM_RES data error'))
|
|
442
455
|
}
|
|
@@ -455,13 +468,14 @@ export class IOCore extends EventEmitter {
|
|
|
455
468
|
let quotaLevel = buffer[1]
|
|
456
469
|
this.level = quotaLevel;
|
|
457
470
|
this.quota = quotaTable[quotaLevel];
|
|
458
|
-
console.log('
|
|
471
|
+
console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
459
472
|
break;
|
|
460
473
|
|
|
461
474
|
case IOMsg.SERVER_CLEAR_AUTH:
|
|
462
475
|
this.useAuth = false;
|
|
463
476
|
this.boho.clearAuth();
|
|
464
477
|
this.stop();
|
|
478
|
+
console.log('[SERVER_CLEAR_AUTH] io stop.')
|
|
465
479
|
break;
|
|
466
480
|
|
|
467
481
|
case IOMsg.SERVER_REDIRECT:
|
|
@@ -668,7 +682,7 @@ export class IOCore extends EventEmitter {
|
|
|
668
682
|
*/
|
|
669
683
|
echo(args) {
|
|
670
684
|
if (args) {
|
|
671
|
-
console.log('echo args:', args)
|
|
685
|
+
// console.log('send echo args:', args)
|
|
672
686
|
this.send_enc_mode(MBP.pack(
|
|
673
687
|
MBP.MB('#MsgType', '8', IOMsg.ECHO),
|
|
674
688
|
MBP.MB('#msg', args)
|
|
@@ -757,13 +771,13 @@ export class IOCore extends EventEmitter {
|
|
|
757
771
|
*/
|
|
758
772
|
setMsgPromise(mid) {
|
|
759
773
|
return new Promise((resolve, reject) => {
|
|
760
|
-
|
|
761
|
-
setTimeout(e => {
|
|
774
|
+
const timeoutId = setTimeout(e => {
|
|
762
775
|
if (this.promiseMap.has(mid)) {
|
|
763
776
|
reject('timeout');
|
|
764
777
|
this.promiseMap.delete(mid)
|
|
765
778
|
}
|
|
766
779
|
}, this.promiseTimeOut);
|
|
780
|
+
this.promiseMap.set(mid, [resolve, reject, timeoutId]);
|
|
767
781
|
})
|
|
768
782
|
}
|
|
769
783
|
|
|
@@ -777,7 +791,8 @@ export class IOCore extends EventEmitter {
|
|
|
777
791
|
if (!res) return
|
|
778
792
|
|
|
779
793
|
if (this.promiseMap.has(res.mid)) {
|
|
780
|
-
let [resolve, reject] = this.promiseMap.get(res.mid)
|
|
794
|
+
let [resolve, reject, timeoutId] = this.promiseMap.get(res.mid)
|
|
795
|
+
clearTimeout(timeoutId)
|
|
781
796
|
this.promiseMap.delete(res.mid)
|
|
782
797
|
|
|
783
798
|
if (res.status < 128) {
|
|
@@ -886,9 +901,9 @@ export class IOCore extends EventEmitter {
|
|
|
886
901
|
|
|
887
902
|
|
|
888
903
|
/**
|
|
889
|
-
* Sends a request to a target and topic.
|
|
890
|
-
* @param {string} target - The target of the request.
|
|
891
|
-
* @param {string} topic - The topic of the request.
|
|
904
|
+
* Sends a request to a target and topic.(remote api call)
|
|
905
|
+
* @param {string} target - The target(api name) of the request.
|
|
906
|
+
* @param {string} topic - The topic(api function name) of the request.
|
|
892
907
|
* @param {...any} args - Optional arguments for the request.
|
|
893
908
|
* @returns {Promise<any>}
|
|
894
909
|
*/
|
|
@@ -1164,6 +1179,7 @@ export class IOCore extends EventEmitter {
|
|
|
1164
1179
|
// STATES constant name : string upperCase
|
|
1165
1180
|
// eventName, .stateName : string lowerCase
|
|
1166
1181
|
// .state : number
|
|
1182
|
+
// console.log('### stateChange reason:', emitEventAndMessage )
|
|
1167
1183
|
let eventName = state.toLowerCase()
|
|
1168
1184
|
this.state = STATES[state.toUpperCase()] // state: number
|
|
1169
1185
|
if (emitEventAndMessage) this.emit(eventName, emitEventAndMessage)
|
package/src/server/Manager.js
CHANGED
|
@@ -193,11 +193,11 @@ export class Manager {
|
|
|
193
193
|
}
|
|
194
194
|
|
|
195
195
|
sender(tag, remote, message) {
|
|
196
|
-
if (serverOption.
|
|
197
|
-
|
|
196
|
+
if (serverOption.membersOnly && !remote.boho.isAuthorized) {
|
|
197
|
+
console.log("[membersOnly] unAuthorized remote.",tag )
|
|
198
198
|
remote.send(Buffer.from([IOMsg.SERVER_CLEAR_AUTH]))
|
|
199
199
|
remote.close()
|
|
200
|
-
return ['err', '
|
|
200
|
+
return ['err', 'unAuthorized']
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
if (tag.indexOf('$') == 0) return ['err', 'prefix $ is reserved for userSet tag.']
|
|
@@ -429,5 +429,20 @@ export class Manager {
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
+
close() {
|
|
433
|
+
clearInterval(this.pingIntervalID);
|
|
434
|
+
if (this.monitIntervalID) {
|
|
435
|
+
clearInterval(this.monitIntervalID);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
this.remotes.forEach(remote => {
|
|
439
|
+
remote.close();
|
|
440
|
+
});
|
|
432
441
|
|
|
442
|
+
this.remotes.clear();
|
|
443
|
+
this.cid2remote.clear();
|
|
444
|
+
this.retain_messages.clear();
|
|
445
|
+
this.channel_map.clear();
|
|
446
|
+
|
|
447
|
+
}
|
|
433
448
|
}
|
package/src/server/Metric.js
CHANGED
|
@@ -118,8 +118,7 @@ export class Metric {
|
|
|
118
118
|
ip: remote.ip,
|
|
119
119
|
uptime: Math.trunc((Date.now() - remote.socket.openTime) / 1000),
|
|
120
120
|
nick: remote.nick,
|
|
121
|
-
ssid: remote.ssid
|
|
122
|
-
echo: remote.lastEchoMessage
|
|
121
|
+
ssid: remote.ssid
|
|
123
122
|
}
|
|
124
123
|
} else if (mode == 3) {
|
|
125
124
|
return {
|
package/src/server/Remote.js
CHANGED
|
@@ -40,6 +40,8 @@ export class Remote extends RemoteCore {
|
|
|
40
40
|
socket.on("ping", this.receiveMonitor.bind(this));
|
|
41
41
|
socket.on("error", (e) => { console.log('Websocket error', e, e.code) });
|
|
42
42
|
socket.onclose = (e) => {
|
|
43
|
+
// Clean up all listeners on the socket to prevent leaks
|
|
44
|
+
socket.removeAllListeners();
|
|
43
45
|
this.manager.removeRemote(this);
|
|
44
46
|
};
|
|
45
47
|
} else { // TCP else
|
|
@@ -59,6 +61,9 @@ export class Remote extends RemoteCore {
|
|
|
59
61
|
|
|
60
62
|
socket.on('error', e => { console.log('TCP Socket error', e) })
|
|
61
63
|
socket.on('close', e => {
|
|
64
|
+
// Clean up listeners on both the socket and the parser
|
|
65
|
+
socket.removeAllListeners();
|
|
66
|
+
this.congRx.removeAllListeners();
|
|
62
67
|
this.manager.removeRemote(this);
|
|
63
68
|
})
|
|
64
69
|
|