iosignal 4.0.0 → 4.5.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/.vscode/settings.json +1 -1
- package/README.md +0 -2
- package/dist/io.d.ts +11 -9
- package/dist/io.js +5 -5
- package/dist/io.js.map +1 -1
- package/dist/io.min.js +5 -5
- package/dist/io.min.js.map +1 -1
- package/dist/iosignal.js +278 -242
- package/dist/types/client/IOCore.d.ts +12 -10
- package/dist/types/common/constants.d.ts +27 -37
- package/index.js +4 -3
- package/package.json +1 -1
- package/src/auth/BohoAuth.js +48 -11
- package/src/auth/{Auth_File.js → key_providers/FileKeyProvider.js} +8 -20
- package/src/auth/{Auth_Redis.js → key_providers/RedisKeyProvider.js} +4 -7
- package/src/auth/key_providers/StringKeyProvider.js +54 -0
- package/src/client/IOCongSocket.js +5 -3
- package/src/client/IOCore.js +64 -65
- package/src/client/IOWS.js +5 -3
- package/src/client/browser/IOWebSocket.js +5 -3
- package/src/common/constants.js +31 -44
- package/src/common/util.js +3 -0
- package/src/server/Manager.js +4 -4
- package/src/server/Remote.js +4 -1
- package/src/server/RemoteCore.js +23 -17
- package/src/server/Server.js +7 -7
- package/README.en.md +0 -56
- package/auth_file_sample.js +0 -23
- package/auth_file_sample.json +0 -13
- package/src/auth/Auth_Env.js +0 -76
package/src/client/IOCore.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import MBP from 'meta-buffer-pack'
|
|
2
2
|
import EventEmitter from "eventemitter3";
|
|
3
|
-
import { IOMsg, PAYLOAD_TYPE, SIZE_LIMIT, ENC_MODE,
|
|
3
|
+
import { IOMsg, PAYLOAD_TYPE, SIZE_LIMIT, ENC_MODE, STATE } from '../common/constants.js'
|
|
4
4
|
import { quotaTable } from '../common/quotaTable.js'
|
|
5
5
|
import { getSignalPack } from '../common/payload.js';
|
|
6
6
|
import Boho from "boho";
|
|
@@ -11,7 +11,7 @@ import Boho from "boho";
|
|
|
11
11
|
* @typedef {import('../common/constants.js').PAYLOAD_TYPE} PAYLOAD_TYPE
|
|
12
12
|
* @typedef {import('../common/constants.js').SIZE_LIMIT} SIZE_LIMIT
|
|
13
13
|
* @typedef {import('../common/constants.js').ENC_MODE} ENC_MODE
|
|
14
|
-
* @typedef {import('../common/constants.js').
|
|
14
|
+
* @typedef {import('../common/constants.js').STATE} STATE
|
|
15
15
|
* @typedef {import('../common/quotaTable.js').quotaTable} quotaTable
|
|
16
16
|
|
|
17
17
|
* @typedef {import('boho').Boho} Boho
|
|
@@ -65,7 +65,7 @@ export class IOCore extends EventEmitter {
|
|
|
65
65
|
* Current connection state (number).
|
|
66
66
|
* @type {number}
|
|
67
67
|
*/
|
|
68
|
-
this.state =
|
|
68
|
+
this.state = STATE.CLOSED; // Number type
|
|
69
69
|
/**
|
|
70
70
|
* Current connection state (string).
|
|
71
71
|
* @type {string}
|
|
@@ -207,7 +207,7 @@ export class IOCore extends EventEmitter {
|
|
|
207
207
|
close() {
|
|
208
208
|
if (this._closed) return;
|
|
209
209
|
this._closed = true;
|
|
210
|
-
// console.log('####### IOCOre.js close() called')
|
|
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);
|
|
@@ -222,7 +222,7 @@ export class IOCore extends EventEmitter {
|
|
|
222
222
|
// To avoid the error, we wait for the connection to open, then immediately close it.
|
|
223
223
|
// We also clear other handlers to prevent any other logic from running.
|
|
224
224
|
const socket = this.socket;
|
|
225
|
-
socket.onopen = () => { if(socket) socket.close(); };
|
|
225
|
+
socket.onopen = () => { if (socket) socket.close(); };
|
|
226
226
|
socket.onmessage = null;
|
|
227
227
|
socket.onerror = null;
|
|
228
228
|
socket.onclose = null;
|
|
@@ -230,7 +230,7 @@ export class IOCore extends EventEmitter {
|
|
|
230
230
|
try {
|
|
231
231
|
// For other sockets (like TCP) or other WebSocket states, close directly.
|
|
232
232
|
this.socket.close?.();
|
|
233
|
-
} catch {}
|
|
233
|
+
} catch { }
|
|
234
234
|
}
|
|
235
235
|
this.socket = null;
|
|
236
236
|
}
|
|
@@ -238,14 +238,15 @@ export class IOCore extends EventEmitter {
|
|
|
238
238
|
this.emit('closed');
|
|
239
239
|
this.stateChange('closed');
|
|
240
240
|
}
|
|
241
|
-
|
|
241
|
+
|
|
242
242
|
/**
|
|
243
243
|
* Disables auto-reconnect and closes the current connection.
|
|
244
244
|
* The instance can be re-opened manually later. For complete cleanup, use destroy().
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
*/
|
|
246
|
+
stop() {
|
|
247
|
+
this.autoReconnect = false;
|
|
248
|
+
this.close();
|
|
249
|
+
this.stateChange('stop','stop');
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
/**
|
|
@@ -261,7 +262,7 @@ export class IOCore extends EventEmitter {
|
|
|
261
262
|
|
|
262
263
|
// Help GC
|
|
263
264
|
this.boho = null;
|
|
264
|
-
}
|
|
265
|
+
}
|
|
265
266
|
|
|
266
267
|
/**
|
|
267
268
|
* The core keep-alive logic. It checks if auto-reconnect is enabled.
|
|
@@ -278,8 +279,8 @@ export class IOCore extends EventEmitter {
|
|
|
278
279
|
* @param {string} url2 - The new URL to redirect to.
|
|
279
280
|
*/
|
|
280
281
|
redirect(url2) {
|
|
282
|
+
this.stateChange('redirecting','redirecting')
|
|
281
283
|
this.close()
|
|
282
|
-
this.stateChange('redirecting')
|
|
283
284
|
this.createConnection(url2)
|
|
284
285
|
}
|
|
285
286
|
|
|
@@ -336,29 +337,27 @@ export class IOCore extends EventEmitter {
|
|
|
336
337
|
|
|
337
338
|
/**
|
|
338
339
|
* Manually logs in with provided ID and key.
|
|
339
|
-
* @param {string} id - The user ID.
|
|
340
|
+
* @param {string} id - The user ID. or 'id.key'
|
|
340
341
|
* @param {string} key - The user key.
|
|
341
|
-
* @returns {
|
|
342
|
+
* @returns {this}
|
|
342
343
|
*/
|
|
343
344
|
login(id, key) {
|
|
344
|
-
|
|
345
|
-
|
|
345
|
+
this.auth(id, key)
|
|
346
346
|
this.useAuth = true
|
|
347
347
|
let auth_pack = this.boho.auth_req()
|
|
348
348
|
this.send(auth_pack)
|
|
349
|
-
return
|
|
349
|
+
return this
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
/**
|
|
353
353
|
* Sets up authentication for auto-login.
|
|
354
|
-
* @param {string} id - The user ID.
|
|
354
|
+
* @param {string} id - The user ID. or 'id.Key'
|
|
355
355
|
* @param {string} key - The user key.
|
|
356
|
-
* @returns {
|
|
356
|
+
* @returns {this}
|
|
357
357
|
*/
|
|
358
358
|
auth(id, key) {
|
|
359
359
|
if (!id && !key) {
|
|
360
360
|
this.emit('error', new Error('auth failed. no id and key.'))
|
|
361
|
-
return false
|
|
362
361
|
}
|
|
363
362
|
|
|
364
363
|
if (!key && id.includes('.')) {
|
|
@@ -368,10 +367,9 @@ export class IOCore extends EventEmitter {
|
|
|
368
367
|
this.boho.set_key(key)
|
|
369
368
|
} else {
|
|
370
369
|
this.emit('error', new Error('auth failed. no id or key.'))
|
|
371
|
-
return false
|
|
372
370
|
}
|
|
373
371
|
this.useAuth = true
|
|
374
|
-
return
|
|
372
|
+
return this
|
|
375
373
|
}
|
|
376
374
|
|
|
377
375
|
/**
|
|
@@ -433,13 +431,13 @@ export class IOCore extends EventEmitter {
|
|
|
433
431
|
case IOMsg.ECHO:
|
|
434
432
|
try {
|
|
435
433
|
let str = decoder.decode(buffer.subarray(1))
|
|
436
|
-
|
|
434
|
+
|
|
437
435
|
this.emit('echo', str)
|
|
438
436
|
} catch (error) {
|
|
439
437
|
this.emit('error', new Error('ECHO data error'))
|
|
440
438
|
}
|
|
441
439
|
break;
|
|
442
|
-
|
|
440
|
+
|
|
443
441
|
case IOMsg.IAM_RES:
|
|
444
442
|
try {
|
|
445
443
|
let str = decoder.decode(buffer.subarray(1))
|
|
@@ -448,7 +446,7 @@ export class IOCore extends EventEmitter {
|
|
|
448
446
|
if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
|
|
449
447
|
if (jsonInfo.did) { this.did = jsonInfo.did; }
|
|
450
448
|
if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
|
|
451
|
-
this.emit('iam_res', str
|
|
449
|
+
this.emit('iam_res', str)
|
|
452
450
|
} catch (error) {
|
|
453
451
|
this.emit('error', new Error('IAM_RES data error'))
|
|
454
452
|
}
|
|
@@ -459,22 +457,22 @@ export class IOCore extends EventEmitter {
|
|
|
459
457
|
this.cid = cidStr;
|
|
460
458
|
|
|
461
459
|
// **IMPORTANT** change state before subscribe.
|
|
462
|
-
this.stateChange('ready', 'cid_ready')
|
|
463
|
-
this.subscribe_memory_channels()
|
|
460
|
+
this.stateChange('ready', 'cid_ready')
|
|
461
|
+
this.subscribe_memory_channels() // tags registered by listen() or link().
|
|
464
462
|
break;
|
|
465
463
|
|
|
466
464
|
case IOMsg.QUOTA_LEVEL:
|
|
467
465
|
let quotaLevel = buffer[1]
|
|
468
466
|
this.level = quotaLevel;
|
|
469
467
|
this.quota = quotaTable[quotaLevel];
|
|
470
|
-
console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
468
|
+
// console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
471
469
|
break;
|
|
472
470
|
|
|
473
|
-
case IOMsg.
|
|
471
|
+
case IOMsg.AUTH_CLEAR:
|
|
474
472
|
this.useAuth = false;
|
|
475
473
|
this.boho.clearAuth();
|
|
474
|
+
this.stateChange('auth_clear', 'server request auth_clear.')
|
|
476
475
|
this.stop();
|
|
477
|
-
console.log('[SERVER_CLEAR_AUTH] io stop.')
|
|
478
476
|
break;
|
|
479
477
|
|
|
480
478
|
case IOMsg.SERVER_REDIRECT:
|
|
@@ -554,7 +552,7 @@ export class IOCore extends EventEmitter {
|
|
|
554
552
|
if (tag.indexOf('@') === 0) this.emit('@', tag, null)
|
|
555
553
|
else {
|
|
556
554
|
this.emit(tag, tag, null)
|
|
557
|
-
this.emit('message', tag, null
|
|
555
|
+
this.emit('message', tag, null)
|
|
558
556
|
}
|
|
559
557
|
break;
|
|
560
558
|
|
|
@@ -567,7 +565,7 @@ export class IOCore extends EventEmitter {
|
|
|
567
565
|
}
|
|
568
566
|
let oneString = decoder.decode(payloadStringWithoutNull)
|
|
569
567
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneString)
|
|
570
|
-
if (tag !== '@'){
|
|
568
|
+
if (tag !== '@') {
|
|
571
569
|
this.emit(tag, tag, oneString)
|
|
572
570
|
this.emit('message', tag, oneString)
|
|
573
571
|
}
|
|
@@ -575,39 +573,39 @@ export class IOCore extends EventEmitter {
|
|
|
575
573
|
|
|
576
574
|
case PAYLOAD_TYPE.BINARY:
|
|
577
575
|
if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer)
|
|
578
|
-
if (tag !== '@'){
|
|
576
|
+
if (tag !== '@') {
|
|
579
577
|
this.emit(tag, tag, payloadBuffer)
|
|
580
578
|
this.emit('message', tag, payloadBuffer)
|
|
581
|
-
}
|
|
579
|
+
}
|
|
582
580
|
break;
|
|
583
581
|
|
|
584
582
|
case PAYLOAD_TYPE.OBJECT:
|
|
585
583
|
let oneObjectBuffer = decoder.decode(payloadBuffer)
|
|
586
584
|
let oneJSONObject = JSON.parse(oneObjectBuffer)
|
|
587
585
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject)
|
|
588
|
-
if (tag !== '@'){
|
|
586
|
+
if (tag !== '@') {
|
|
589
587
|
this.emit(tag, tag, oneJSONObject)
|
|
590
588
|
this.emit('message', tag, oneJSONObject)
|
|
591
|
-
}
|
|
589
|
+
}
|
|
592
590
|
break;
|
|
593
591
|
|
|
594
592
|
case PAYLOAD_TYPE.MJSON:
|
|
595
593
|
let mjsonBuffer = decoder.decode(payloadBuffer)
|
|
596
594
|
let mjson = JSON.parse(mjsonBuffer)
|
|
597
595
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson)
|
|
598
|
-
if (tag !== '@'){
|
|
596
|
+
if (tag !== '@') {
|
|
599
597
|
this.emit(tag, tag, ...mjson)
|
|
600
598
|
this.emit('message', tag, ...mjson)
|
|
601
|
-
}
|
|
599
|
+
}
|
|
602
600
|
break;
|
|
603
601
|
|
|
604
602
|
case PAYLOAD_TYPE.MBA:
|
|
605
603
|
let mbaObject = MBP.unpack(payloadBuffer)
|
|
606
604
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args)
|
|
607
|
-
if (tag !== '@'){
|
|
605
|
+
if (tag !== '@') {
|
|
608
606
|
this.emit(tag, tag, ...mbaObject.args)
|
|
609
|
-
this.emit('message', tag, ...mbaObject.args
|
|
610
|
-
}
|
|
607
|
+
this.emit('message', tag, ...mbaObject.args)
|
|
608
|
+
}
|
|
611
609
|
break;
|
|
612
610
|
|
|
613
611
|
default:
|
|
@@ -615,7 +613,8 @@ export class IOCore extends EventEmitter {
|
|
|
615
613
|
}
|
|
616
614
|
|
|
617
615
|
} catch (err) {
|
|
618
|
-
this.emit('error', new Error('
|
|
616
|
+
// this.emit('error', new Error('IOCore IOMsg.SIGNAL parser err', err))
|
|
617
|
+
console.log('IOCore IOMsg.SIGNAL parser err', err)
|
|
619
618
|
}
|
|
620
619
|
break;
|
|
621
620
|
|
|
@@ -624,24 +623,25 @@ export class IOCore extends EventEmitter {
|
|
|
624
623
|
break;
|
|
625
624
|
|
|
626
625
|
case Boho.BohoMsg.AUTH_NONCE:
|
|
626
|
+
this.stateChange('auth_nonce','server sent auth_nonce.')
|
|
627
627
|
let auth_hmac = this.boho.auth_hmac(buffer)
|
|
628
628
|
if (auth_hmac) {
|
|
629
629
|
this.send(auth_hmac)
|
|
630
630
|
} else {
|
|
631
|
-
this.stateChange('auth_fail', '
|
|
631
|
+
this.stateChange('auth_fail', 'boho.auth_hmac() invalid auth_nonce.')
|
|
632
632
|
}
|
|
633
633
|
break;
|
|
634
634
|
|
|
635
635
|
case Boho.BohoMsg.AUTH_FAIL:
|
|
636
|
-
this.stateChange('auth_fail', '
|
|
636
|
+
this.stateChange('auth_fail', 'auth_fail from server.')
|
|
637
637
|
break;
|
|
638
638
|
|
|
639
639
|
case Boho.BohoMsg.AUTH_ACK:
|
|
640
640
|
if (this.boho.check_auth_ack_hmac(buffer)) {
|
|
641
|
-
this.stateChange('
|
|
641
|
+
this.stateChange('auth_ack', 'server sent auth_ack')
|
|
642
642
|
this.send(Buffer.from([IOMsg.CID_REQ]))
|
|
643
643
|
} else {
|
|
644
|
-
this.stateChange('auth_fail', 'invalid server_hmac')
|
|
644
|
+
this.stateChange('auth_fail', 'check_auth_ack_hmac() invalid server_hmac')
|
|
645
645
|
}
|
|
646
646
|
break;
|
|
647
647
|
|
|
@@ -828,14 +828,15 @@ export class IOCore extends EventEmitter {
|
|
|
828
828
|
|
|
829
829
|
|
|
830
830
|
/**
|
|
831
|
-
*
|
|
831
|
+
* alias of signal()
|
|
832
|
+
* Sends a signal with a tag and arguments.
|
|
833
|
+
* @param {string} tag - The signal tag.
|
|
832
834
|
* @param {...any} args - Arguments for the signal.
|
|
833
835
|
*/
|
|
834
|
-
publish(...args) {
|
|
835
|
-
this.signal(...args)
|
|
836
|
+
publish(tag, ...args) {
|
|
837
|
+
this.signal(tag, ...args)
|
|
836
838
|
}
|
|
837
839
|
|
|
838
|
-
|
|
839
840
|
/**
|
|
840
841
|
* Sends a signal with a tag and arguments.
|
|
841
842
|
* @param {string} tag - The signal tag.
|
|
@@ -844,7 +845,6 @@ export class IOCore extends EventEmitter {
|
|
|
844
845
|
*/
|
|
845
846
|
signal(tag, ...args) {
|
|
846
847
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
847
|
-
|
|
848
848
|
let signalPack = getSignalPack(tag, ...args)
|
|
849
849
|
this.send_enc_mode(signalPack)
|
|
850
850
|
}
|
|
@@ -888,7 +888,6 @@ export class IOCore extends EventEmitter {
|
|
|
888
888
|
}
|
|
889
889
|
|
|
890
890
|
|
|
891
|
-
|
|
892
891
|
/**
|
|
893
892
|
* Sets a value in the store.
|
|
894
893
|
* @param {string} storeName - The name of the store.
|
|
@@ -956,8 +955,8 @@ export class IOCore extends EventEmitter {
|
|
|
956
955
|
*/
|
|
957
956
|
subscribe(tag) {
|
|
958
957
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
959
|
-
|
|
960
|
-
if (this.state !==
|
|
958
|
+
if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
|
|
959
|
+
if (this.state !== STATE.READY) return
|
|
961
960
|
|
|
962
961
|
// subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
|
|
963
962
|
// 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
|
|
@@ -966,7 +965,7 @@ export class IOCore extends EventEmitter {
|
|
|
966
965
|
// this.channels.add(tag)
|
|
967
966
|
// })
|
|
968
967
|
|
|
969
|
-
try {
|
|
968
|
+
try {
|
|
970
969
|
let tagEncoded = encoder.encode(tag)
|
|
971
970
|
this.send_enc_mode(
|
|
972
971
|
Buffer.concat([
|
|
@@ -986,12 +985,12 @@ export class IOCore extends EventEmitter {
|
|
|
986
985
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
987
986
|
if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
|
|
988
987
|
|
|
989
|
-
if (this.state !==
|
|
988
|
+
if (this.state !== STATE.READY) {
|
|
990
989
|
return Promise.reject('subscribe_promise:: connection is not ready')
|
|
991
990
|
}
|
|
992
991
|
|
|
993
992
|
try {
|
|
994
|
-
let tagEncoded = encoder.encode(tag)
|
|
993
|
+
let tagEncoded = encoder.encode(tag)
|
|
995
994
|
this.send_enc_mode(
|
|
996
995
|
Buffer.concat([
|
|
997
996
|
MBP.NB('8', IOMsg.SUBSCRIBE_REQ),
|
|
@@ -1061,7 +1060,7 @@ export class IOCore extends EventEmitter {
|
|
|
1061
1060
|
}
|
|
1062
1061
|
this.on(tag, handler)
|
|
1063
1062
|
// do not subscribe now.
|
|
1064
|
-
// will subscribe when receive CID_RES
|
|
1063
|
+
// will subscribe when io state is 'ready'. (receive CID_RES from server)
|
|
1065
1064
|
|
|
1066
1065
|
}
|
|
1067
1066
|
|
|
@@ -1172,10 +1171,10 @@ export class IOCore extends EventEmitter {
|
|
|
1172
1171
|
*/
|
|
1173
1172
|
getStateName() {
|
|
1174
1173
|
//state <number>
|
|
1175
|
-
//value of constant
|
|
1176
|
-
//type of constant
|
|
1174
|
+
//value of constant STATE.NAME < number >
|
|
1175
|
+
//type of constant STATE.NAME name < string uppercase >
|
|
1177
1176
|
//stateName,eventName <string lowercase>
|
|
1178
|
-
return (
|
|
1177
|
+
return (STATE[this.state]).toLowerCase()
|
|
1179
1178
|
}
|
|
1180
1179
|
|
|
1181
1180
|
/**
|
|
@@ -1203,14 +1202,14 @@ export class IOCore extends EventEmitter {
|
|
|
1203
1202
|
* 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
|
|
1204
1203
|
*/
|
|
1205
1204
|
stateChange(state, emitEventAndMessage) {
|
|
1206
|
-
//
|
|
1205
|
+
// STATE constant name <string> upperCase
|
|
1207
1206
|
// eventName and .stateName <string> lowerCase
|
|
1208
1207
|
// .state <number>
|
|
1209
1208
|
// console.log('### stateChange reason:', emitEventAndMessage )
|
|
1210
1209
|
let eventName = state.toLowerCase()
|
|
1211
|
-
this.state =
|
|
1210
|
+
this.state = STATE[state.toUpperCase()] // state: number
|
|
1212
1211
|
|
|
1213
|
-
if (emitEventAndMessage){
|
|
1212
|
+
if (emitEventAndMessage) {
|
|
1214
1213
|
this.emit(eventName, emitEventAndMessage)
|
|
1215
1214
|
}
|
|
1216
1215
|
|
package/src/client/IOWS.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IOCore } from "./IOCore.js";
|
|
2
|
-
import {
|
|
2
|
+
import { STATE } from "../common/constants.js";
|
|
3
3
|
import { WebSocket } from "ws";
|
|
4
4
|
|
|
5
5
|
// Node.js 'ws' websocket
|
|
@@ -28,15 +28,17 @@ export class IOWS extends IOCore {
|
|
|
28
28
|
keepAlive() {
|
|
29
29
|
if (!this.autoReconnect) return;
|
|
30
30
|
// Reconnect only if the socket is closed and the state reflects that.
|
|
31
|
-
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED)
|
|
31
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
|
|
32
32
|
this.open();
|
|
33
|
+
}else{
|
|
34
|
+
this.ping();
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
createConnection(url) {
|
|
37
39
|
// node WebSocket
|
|
38
40
|
this.socket = new WebSocket(url);
|
|
39
|
-
this.stateChange('
|
|
41
|
+
this.stateChange('connecting','connecting')
|
|
40
42
|
|
|
41
43
|
this.socket.onopen = () => {
|
|
42
44
|
this.socket.on('message', this.onWebSocketMessage.bind(this));
|
|
@@ -104,13 +104,15 @@ export default class IO extends IOCore {
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
* Keeps the connection alive by re-
|
|
107
|
+
* Keeps the connection alive by re-connecting if closed.
|
|
108
108
|
*/
|
|
109
109
|
keepAlive() {
|
|
110
110
|
if (!this.autoReconnect) return;
|
|
111
111
|
// Reconnect only if the socket is closed and the state reflects that.
|
|
112
|
-
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED)
|
|
112
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
|
|
113
113
|
this.open();
|
|
114
|
+
}else{
|
|
115
|
+
this.ping();
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -126,7 +128,7 @@ export default class IO extends IOCore {
|
|
|
126
128
|
this.socket = new WebSocket(url);
|
|
127
129
|
this.socket.binaryType = IO.binaryType
|
|
128
130
|
|
|
129
|
-
this.stateChange('
|
|
131
|
+
this.stateChange('connecting','connecting')
|
|
130
132
|
|
|
131
133
|
this.socket.onopen = () => {
|
|
132
134
|
|
package/src/common/constants.js
CHANGED
|
@@ -1,52 +1,40 @@
|
|
|
1
1
|
|
|
2
2
|
/**
|
|
3
|
-
* @typedef {object}
|
|
4
|
-
* @property {number}
|
|
3
|
+
* @typedef {object} STATE
|
|
4
|
+
* @property {number} CONNECTING
|
|
5
5
|
* @property {number} OPEN
|
|
6
|
-
* @property {number} CLOSING
|
|
7
|
-
* @property {number} CLOSED
|
|
8
6
|
* @property {number} SERVER_READY
|
|
9
|
-
* @property {number}
|
|
10
|
-
* @property {number}
|
|
7
|
+
* @property {number} AUTH_ACK
|
|
8
|
+
* @property {number} CLOSING
|
|
11
9
|
* @property {number} READY
|
|
10
|
+
* @property {number} AUTH_FAIL
|
|
11
|
+
* @property {number} AUTH_CLEAR
|
|
12
|
+
* @property {number} CLOSING
|
|
13
|
+
* @property {number} CLOSED
|
|
14
|
+
* @property {number} STOP
|
|
12
15
|
* @property {number} REDIRECTING
|
|
13
16
|
*/
|
|
14
|
-
// Client
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
OPEN:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
// Client STATE: name and number
|
|
18
|
+
export const STATE = {
|
|
19
|
+
CONNECTING: 0,
|
|
20
|
+
OPEN: 1,
|
|
21
|
+
SERVER_READY: 10,
|
|
22
|
+
AUTH_REQ: 11,
|
|
23
|
+
AUTH_NONCE: 12,
|
|
24
|
+
AUTH_HMAC: 13,
|
|
25
|
+
AUTH_ACK: 14,
|
|
26
|
+
AUTH_FAIL: 15,
|
|
27
|
+
AUTH_CLEAR: 16,
|
|
28
|
+
CID_REQ: 17,
|
|
29
|
+
CID_RES: 18,
|
|
30
|
+
READY: 19,
|
|
31
|
+
CLOSING: 2,
|
|
32
|
+
CLOSED: 3,
|
|
33
|
+
STOP: 4,
|
|
34
|
+
REDIRECTING: 5
|
|
25
35
|
}
|
|
26
|
-
for (let c in
|
|
36
|
+
for (let c in STATE) { STATE[STATE[c]] = c }
|
|
27
37
|
|
|
28
|
-
/**
|
|
29
|
-
* @typedef {object} CLIENT_STATE
|
|
30
|
-
* @property {number} INIT
|
|
31
|
-
* @property {number} SENT_SERVER_READY
|
|
32
|
-
* @property {number} RECV_AUTH_REQ
|
|
33
|
-
* @property {number} SENT_SERVER_NONCE
|
|
34
|
-
* @property {number} RECV_AUTH_HMAC
|
|
35
|
-
* @property {number} AUTH_FAIL
|
|
36
|
-
* @property {number} AUTH_READY
|
|
37
|
-
* @property {number} CID_READY
|
|
38
|
-
*/
|
|
39
|
-
export const CLIENT_STATE = {
|
|
40
|
-
INIT: 0,
|
|
41
|
-
SENT_SERVER_READY: 1,
|
|
42
|
-
RECV_AUTH_REQ: 2,
|
|
43
|
-
SENT_SERVER_NONCE: 3,
|
|
44
|
-
RECV_AUTH_HMAC: 4,
|
|
45
|
-
AUTH_FAIL: 5,
|
|
46
|
-
AUTH_READY: 6,
|
|
47
|
-
CID_READY: 7
|
|
48
|
-
}
|
|
49
|
-
for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
|
|
50
38
|
|
|
51
39
|
/**
|
|
52
40
|
* @typedef {object} ENC_MODE
|
|
@@ -75,7 +63,7 @@ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
|
|
|
75
63
|
export const SIZE_LIMIT = {
|
|
76
64
|
TAG_LEN1: 255,
|
|
77
65
|
TAG_LEN2: 65535,
|
|
78
|
-
CONNECTION_CHECKER_PERIOD:
|
|
66
|
+
CONNECTION_CHECKER_PERIOD: 30000,
|
|
79
67
|
PROMISE_TIMEOUT: 5000,
|
|
80
68
|
DID: 8,
|
|
81
69
|
CID: 12
|
|
@@ -107,7 +95,7 @@ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
|
|
|
107
95
|
* @property {number} CID_REQ
|
|
108
96
|
* @property {number} CID_RES
|
|
109
97
|
* @property {number} QUOTA_LEVEL
|
|
110
|
-
* @property {number}
|
|
98
|
+
* @property {number} AUTH_CLEAR
|
|
111
99
|
* @property {number} SERVER_REDIRECT
|
|
112
100
|
* @property {number} LOOP
|
|
113
101
|
* @property {number} ECHO
|
|
@@ -165,9 +153,8 @@ export let IOMsg = {
|
|
|
165
153
|
CID_REQ: 0xC1,
|
|
166
154
|
CID_RES: 0xC2,
|
|
167
155
|
QUOTA_LEVEL: 0xC3,
|
|
168
|
-
|
|
156
|
+
AUTH_CLEAR: 0xC4,
|
|
169
157
|
SERVER_REDIRECT: 0xC5,
|
|
170
|
-
|
|
171
158
|
// ..
|
|
172
159
|
LOOP: 0xCB,
|
|
173
160
|
ECHO: 0xCC,
|
package/src/common/util.js
CHANGED
package/src/server/Manager.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import MBP from 'meta-buffer-pack'
|
|
2
2
|
import { Remote } from './Remote.js'
|
|
3
3
|
import { serverOption } from './serverOption.js'
|
|
4
|
-
import { IOMsg,
|
|
4
|
+
import { IOMsg, STATE } from '../common/constants.js'
|
|
5
5
|
import { getSignalPack } from '../common/payload.js';
|
|
6
6
|
import { FileLogger } from './FileLogger.js'
|
|
7
7
|
import { Metric } from './Metric.js'
|
|
@@ -73,7 +73,7 @@ export class Manager {
|
|
|
73
73
|
let remote = new Remote(socket, req, this)
|
|
74
74
|
this.remotes.add(remote)
|
|
75
75
|
remote.send(Buffer.from([IOMsg.SERVER_READY]))
|
|
76
|
-
remote.setState(
|
|
76
|
+
remote.setState(STATE.SERVER_READY)
|
|
77
77
|
this.lastSSID = remote.ssid;
|
|
78
78
|
let connectionInfo = `+ IP:${remote.ip} #${remote.ssid} ${socket.socketType === 'websocket' ? "WS" : "CS"} `;
|
|
79
79
|
// console.log( connectionInfo)
|
|
@@ -194,8 +194,8 @@ export class Manager {
|
|
|
194
194
|
|
|
195
195
|
sender(tag, remote, message) {
|
|
196
196
|
if (serverOption.membersOnly && !remote.boho.isAuthorized) {
|
|
197
|
-
console.log("[membersOnly]
|
|
198
|
-
remote.send(Buffer.from([IOMsg.
|
|
197
|
+
// console.log("### server reject client signal reason: [membersOnly]" ,tag, remote.cid )
|
|
198
|
+
remote.send(Buffer.from([IOMsg.AUTH_CLEAR]))
|
|
199
199
|
remote.close()
|
|
200
200
|
return ['err', 'unAuthorized']
|
|
201
201
|
}
|
package/src/server/Remote.js
CHANGED
|
@@ -185,6 +185,7 @@ export class Remote extends RemoteCore {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
// node.js server side remote.
|
|
188
189
|
send(message, isBinary) {
|
|
189
190
|
this.manager.txBytes += message.byteLength;
|
|
190
191
|
this.socket.txCounter++;
|
|
@@ -196,13 +197,15 @@ export class Remote extends RemoteCore {
|
|
|
196
197
|
this.socket.send(message);
|
|
197
198
|
}
|
|
198
199
|
} else {
|
|
200
|
+
console.log('server(ws)Remote.send() called. not open state. current readyState:', this.socket.readyState )
|
|
199
201
|
this.close(true)
|
|
200
202
|
}
|
|
201
|
-
|
|
203
|
+
|
|
202
204
|
} else { //CongSocket
|
|
203
205
|
if (this.socket.readyState == 'open') {
|
|
204
206
|
this.socket.write(pack(message))
|
|
205
207
|
} else {
|
|
208
|
+
console.log('server(cong)Remote.send() called. not open state. current readyState:', this.socket.readyState )
|
|
206
209
|
this.close(true)
|
|
207
210
|
}
|
|
208
211
|
}
|