iosignal 4.0.0 → 4.6.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 +18 -11
- 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 +291 -251
- package/dist/types/client/IOCore.d.ts +15 -12
- package/dist/types/client/browser/IOWebSocket.d.ts +4 -0
- package/dist/types/common/constants.d.ts +29 -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 +4 -4
- package/src/client/IOCore.js +71 -70
- package/src/client/IOWS.js +6 -5
- package/src/client/browser/IOWebSocket.js +4 -4
- package/src/common/constants.js +32 -43
- 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 +28 -19
- 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,16 +262,18 @@ export class IOCore extends EventEmitter {
|
|
|
261
262
|
|
|
262
263
|
// Help GC
|
|
263
264
|
this.boho = null;
|
|
264
|
-
}
|
|
265
|
+
}
|
|
265
266
|
|
|
266
267
|
/**
|
|
267
|
-
* The core keep-alive logic.
|
|
268
|
-
* The
|
|
268
|
+
* The core keep-alive logic.
|
|
269
|
+
* The specific logic for checking the socket's state and reconnecting
|
|
270
|
+
* is implemented keepConnection() in the child classes (IOWS, IOCongSocket, etc.).
|
|
269
271
|
*/
|
|
270
272
|
keepAlive() {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
this.keepConnection();
|
|
274
|
+
if( Date.now() - this.lastTxRxTime > SIZE_LIMIT.CLIENT_PING_PERIOD ){
|
|
275
|
+
this.ping();
|
|
276
|
+
}
|
|
274
277
|
}
|
|
275
278
|
|
|
276
279
|
/**
|
|
@@ -278,8 +281,8 @@ export class IOCore extends EventEmitter {
|
|
|
278
281
|
* @param {string} url2 - The new URL to redirect to.
|
|
279
282
|
*/
|
|
280
283
|
redirect(url2) {
|
|
284
|
+
this.stateChange('redirecting','redirecting')
|
|
281
285
|
this.close()
|
|
282
|
-
this.stateChange('redirecting')
|
|
283
286
|
this.createConnection(url2)
|
|
284
287
|
}
|
|
285
288
|
|
|
@@ -336,29 +339,27 @@ export class IOCore extends EventEmitter {
|
|
|
336
339
|
|
|
337
340
|
/**
|
|
338
341
|
* Manually logs in with provided ID and key.
|
|
339
|
-
* @param {string} id - The user ID.
|
|
342
|
+
* @param {string} id - The user ID. or 'id.key'
|
|
340
343
|
* @param {string} key - The user key.
|
|
341
|
-
* @returns {
|
|
344
|
+
* @returns {this}
|
|
342
345
|
*/
|
|
343
346
|
login(id, key) {
|
|
344
|
-
|
|
345
|
-
|
|
347
|
+
this.auth(id, key)
|
|
346
348
|
this.useAuth = true
|
|
347
349
|
let auth_pack = this.boho.auth_req()
|
|
348
350
|
this.send(auth_pack)
|
|
349
|
-
return
|
|
351
|
+
return this
|
|
350
352
|
}
|
|
351
353
|
|
|
352
354
|
/**
|
|
353
355
|
* Sets up authentication for auto-login.
|
|
354
|
-
* @param {string} id - The user ID.
|
|
356
|
+
* @param {string} id - The user ID. or 'id.Key'
|
|
355
357
|
* @param {string} key - The user key.
|
|
356
|
-
* @returns {
|
|
358
|
+
* @returns {this}
|
|
357
359
|
*/
|
|
358
360
|
auth(id, key) {
|
|
359
361
|
if (!id && !key) {
|
|
360
362
|
this.emit('error', new Error('auth failed. no id and key.'))
|
|
361
|
-
return false
|
|
362
363
|
}
|
|
363
364
|
|
|
364
365
|
if (!key && id.includes('.')) {
|
|
@@ -368,10 +369,9 @@ export class IOCore extends EventEmitter {
|
|
|
368
369
|
this.boho.set_key(key)
|
|
369
370
|
} else {
|
|
370
371
|
this.emit('error', new Error('auth failed. no id or key.'))
|
|
371
|
-
return false
|
|
372
372
|
}
|
|
373
373
|
this.useAuth = true
|
|
374
|
-
return
|
|
374
|
+
return this
|
|
375
375
|
}
|
|
376
376
|
|
|
377
377
|
/**
|
|
@@ -433,13 +433,13 @@ export class IOCore extends EventEmitter {
|
|
|
433
433
|
case IOMsg.ECHO:
|
|
434
434
|
try {
|
|
435
435
|
let str = decoder.decode(buffer.subarray(1))
|
|
436
|
-
|
|
436
|
+
|
|
437
437
|
this.emit('echo', str)
|
|
438
438
|
} catch (error) {
|
|
439
439
|
this.emit('error', new Error('ECHO data error'))
|
|
440
440
|
}
|
|
441
441
|
break;
|
|
442
|
-
|
|
442
|
+
|
|
443
443
|
case IOMsg.IAM_RES:
|
|
444
444
|
try {
|
|
445
445
|
let str = decoder.decode(buffer.subarray(1))
|
|
@@ -448,7 +448,7 @@ export class IOCore extends EventEmitter {
|
|
|
448
448
|
if (jsonInfo.nick) { this.nick = jsonInfo.nick; }
|
|
449
449
|
if (jsonInfo.did) { this.did = jsonInfo.did; }
|
|
450
450
|
if (jsonInfo.uid) { this.uid = jsonInfo.uid; }
|
|
451
|
-
this.emit('iam_res', str
|
|
451
|
+
this.emit('iam_res', str)
|
|
452
452
|
} catch (error) {
|
|
453
453
|
this.emit('error', new Error('IAM_RES data error'))
|
|
454
454
|
}
|
|
@@ -459,22 +459,22 @@ export class IOCore extends EventEmitter {
|
|
|
459
459
|
this.cid = cidStr;
|
|
460
460
|
|
|
461
461
|
// **IMPORTANT** change state before subscribe.
|
|
462
|
-
this.stateChange('ready', 'cid_ready')
|
|
463
|
-
this.subscribe_memory_channels()
|
|
462
|
+
this.stateChange('ready', 'cid_ready')
|
|
463
|
+
this.subscribe_memory_channels() // tags registered by listen() or link().
|
|
464
464
|
break;
|
|
465
465
|
|
|
466
466
|
case IOMsg.QUOTA_LEVEL:
|
|
467
467
|
let quotaLevel = buffer[1]
|
|
468
468
|
this.level = quotaLevel;
|
|
469
469
|
this.quota = quotaTable[quotaLevel];
|
|
470
|
-
console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
470
|
+
// console.log('[QUOTA_LEVEL]', JSON.stringify(this.quota))
|
|
471
471
|
break;
|
|
472
472
|
|
|
473
|
-
case IOMsg.
|
|
473
|
+
case IOMsg.AUTH_CLEAR:
|
|
474
474
|
this.useAuth = false;
|
|
475
475
|
this.boho.clearAuth();
|
|
476
|
+
this.stateChange('auth_clear', 'server request auth_clear.')
|
|
476
477
|
this.stop();
|
|
477
|
-
console.log('[SERVER_CLEAR_AUTH] io stop.')
|
|
478
478
|
break;
|
|
479
479
|
|
|
480
480
|
case IOMsg.SERVER_REDIRECT:
|
|
@@ -554,7 +554,7 @@ export class IOCore extends EventEmitter {
|
|
|
554
554
|
if (tag.indexOf('@') === 0) this.emit('@', tag, null)
|
|
555
555
|
else {
|
|
556
556
|
this.emit(tag, tag, null)
|
|
557
|
-
this.emit('message', tag, null
|
|
557
|
+
this.emit('message', tag, null)
|
|
558
558
|
}
|
|
559
559
|
break;
|
|
560
560
|
|
|
@@ -567,7 +567,7 @@ export class IOCore extends EventEmitter {
|
|
|
567
567
|
}
|
|
568
568
|
let oneString = decoder.decode(payloadStringWithoutNull)
|
|
569
569
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneString)
|
|
570
|
-
if (tag !== '@'){
|
|
570
|
+
if (tag !== '@') {
|
|
571
571
|
this.emit(tag, tag, oneString)
|
|
572
572
|
this.emit('message', tag, oneString)
|
|
573
573
|
}
|
|
@@ -575,39 +575,39 @@ export class IOCore extends EventEmitter {
|
|
|
575
575
|
|
|
576
576
|
case PAYLOAD_TYPE.BINARY:
|
|
577
577
|
if (tag.indexOf('@') === 0) this.emit('@', tag, payloadBuffer)
|
|
578
|
-
if (tag !== '@'){
|
|
578
|
+
if (tag !== '@') {
|
|
579
579
|
this.emit(tag, tag, payloadBuffer)
|
|
580
580
|
this.emit('message', tag, payloadBuffer)
|
|
581
|
-
}
|
|
581
|
+
}
|
|
582
582
|
break;
|
|
583
583
|
|
|
584
584
|
case PAYLOAD_TYPE.OBJECT:
|
|
585
585
|
let oneObjectBuffer = decoder.decode(payloadBuffer)
|
|
586
586
|
let oneJSONObject = JSON.parse(oneObjectBuffer)
|
|
587
587
|
if (tag.indexOf('@') === 0) this.emit('@', tag, oneJSONObject)
|
|
588
|
-
if (tag !== '@'){
|
|
588
|
+
if (tag !== '@') {
|
|
589
589
|
this.emit(tag, tag, oneJSONObject)
|
|
590
590
|
this.emit('message', tag, oneJSONObject)
|
|
591
|
-
}
|
|
591
|
+
}
|
|
592
592
|
break;
|
|
593
593
|
|
|
594
594
|
case PAYLOAD_TYPE.MJSON:
|
|
595
595
|
let mjsonBuffer = decoder.decode(payloadBuffer)
|
|
596
596
|
let mjson = JSON.parse(mjsonBuffer)
|
|
597
597
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mjson)
|
|
598
|
-
if (tag !== '@'){
|
|
598
|
+
if (tag !== '@') {
|
|
599
599
|
this.emit(tag, tag, ...mjson)
|
|
600
600
|
this.emit('message', tag, ...mjson)
|
|
601
|
-
}
|
|
601
|
+
}
|
|
602
602
|
break;
|
|
603
603
|
|
|
604
604
|
case PAYLOAD_TYPE.MBA:
|
|
605
605
|
let mbaObject = MBP.unpack(payloadBuffer)
|
|
606
606
|
if (tag.indexOf('@') === 0) this.emit('@', tag, ...mbaObject.args)
|
|
607
|
-
if (tag !== '@'){
|
|
607
|
+
if (tag !== '@') {
|
|
608
608
|
this.emit(tag, tag, ...mbaObject.args)
|
|
609
|
-
this.emit('message', tag, ...mbaObject.args
|
|
610
|
-
}
|
|
609
|
+
this.emit('message', tag, ...mbaObject.args)
|
|
610
|
+
}
|
|
611
611
|
break;
|
|
612
612
|
|
|
613
613
|
default:
|
|
@@ -615,7 +615,8 @@ export class IOCore extends EventEmitter {
|
|
|
615
615
|
}
|
|
616
616
|
|
|
617
617
|
} catch (err) {
|
|
618
|
-
this.emit('error', new Error('
|
|
618
|
+
// this.emit('error', new Error('IOCore IOMsg.SIGNAL parser err', err))
|
|
619
|
+
console.log('IOCore IOMsg.SIGNAL parser err', err)
|
|
619
620
|
}
|
|
620
621
|
break;
|
|
621
622
|
|
|
@@ -624,24 +625,25 @@ export class IOCore extends EventEmitter {
|
|
|
624
625
|
break;
|
|
625
626
|
|
|
626
627
|
case Boho.BohoMsg.AUTH_NONCE:
|
|
628
|
+
this.stateChange('auth_nonce','server sent auth_nonce.')
|
|
627
629
|
let auth_hmac = this.boho.auth_hmac(buffer)
|
|
628
630
|
if (auth_hmac) {
|
|
629
631
|
this.send(auth_hmac)
|
|
630
632
|
} else {
|
|
631
|
-
this.stateChange('auth_fail', '
|
|
633
|
+
this.stateChange('auth_fail', 'boho.auth_hmac() invalid auth_nonce.')
|
|
632
634
|
}
|
|
633
635
|
break;
|
|
634
636
|
|
|
635
637
|
case Boho.BohoMsg.AUTH_FAIL:
|
|
636
|
-
this.stateChange('auth_fail', '
|
|
638
|
+
this.stateChange('auth_fail', 'auth_fail from server.')
|
|
637
639
|
break;
|
|
638
640
|
|
|
639
641
|
case Boho.BohoMsg.AUTH_ACK:
|
|
640
642
|
if (this.boho.check_auth_ack_hmac(buffer)) {
|
|
641
|
-
this.stateChange('
|
|
643
|
+
this.stateChange('auth_ack', 'server sent auth_ack')
|
|
642
644
|
this.send(Buffer.from([IOMsg.CID_REQ]))
|
|
643
645
|
} else {
|
|
644
|
-
this.stateChange('auth_fail', 'invalid server_hmac')
|
|
646
|
+
this.stateChange('auth_fail', 'check_auth_ack_hmac() invalid server_hmac')
|
|
645
647
|
}
|
|
646
648
|
break;
|
|
647
649
|
|
|
@@ -828,14 +830,15 @@ export class IOCore extends EventEmitter {
|
|
|
828
830
|
|
|
829
831
|
|
|
830
832
|
/**
|
|
831
|
-
*
|
|
833
|
+
* alias of signal()
|
|
834
|
+
* Sends a signal with a tag and arguments.
|
|
835
|
+
* @param {string} tag - The signal tag.
|
|
832
836
|
* @param {...any} args - Arguments for the signal.
|
|
833
837
|
*/
|
|
834
|
-
publish(...args) {
|
|
835
|
-
this.signal(...args)
|
|
838
|
+
publish(tag, ...args) {
|
|
839
|
+
this.signal(tag, ...args)
|
|
836
840
|
}
|
|
837
841
|
|
|
838
|
-
|
|
839
842
|
/**
|
|
840
843
|
* Sends a signal with a tag and arguments.
|
|
841
844
|
* @param {string} tag - The signal tag.
|
|
@@ -844,7 +847,6 @@ export class IOCore extends EventEmitter {
|
|
|
844
847
|
*/
|
|
845
848
|
signal(tag, ...args) {
|
|
846
849
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
847
|
-
|
|
848
850
|
let signalPack = getSignalPack(tag, ...args)
|
|
849
851
|
this.send_enc_mode(signalPack)
|
|
850
852
|
}
|
|
@@ -888,7 +890,6 @@ export class IOCore extends EventEmitter {
|
|
|
888
890
|
}
|
|
889
891
|
|
|
890
892
|
|
|
891
|
-
|
|
892
893
|
/**
|
|
893
894
|
* Sets a value in the store.
|
|
894
895
|
* @param {string} storeName - The name of the store.
|
|
@@ -956,8 +957,8 @@ export class IOCore extends EventEmitter {
|
|
|
956
957
|
*/
|
|
957
958
|
subscribe(tag) {
|
|
958
959
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
959
|
-
|
|
960
|
-
if (this.state !==
|
|
960
|
+
if (tag.length > SIZE_LIMIT.TAG_LEN1) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN1)
|
|
961
|
+
if (this.state !== STATE.READY) return
|
|
961
962
|
|
|
962
963
|
// subscribe 사용시, 사용 'ready' 이벤트시 메뉴얼 등록되므로 여기에 등록하면 2중 호출된다.
|
|
963
964
|
// 즉, channels 등록은 listen 같은 자동화 구독시만 사용.
|
|
@@ -966,7 +967,7 @@ export class IOCore extends EventEmitter {
|
|
|
966
967
|
// this.channels.add(tag)
|
|
967
968
|
// })
|
|
968
969
|
|
|
969
|
-
try {
|
|
970
|
+
try {
|
|
970
971
|
let tagEncoded = encoder.encode(tag)
|
|
971
972
|
this.send_enc_mode(
|
|
972
973
|
Buffer.concat([
|
|
@@ -986,12 +987,12 @@ export class IOCore extends EventEmitter {
|
|
|
986
987
|
if (typeof tag !== 'string') throw TypeError('tag should be string.')
|
|
987
988
|
if (tag.length > SIZE_LIMIT.TAG_LEN2) throw TypeError('please check tag string length limit:' + SIZE_LIMIT.TAG_LEN2)
|
|
988
989
|
|
|
989
|
-
if (this.state !==
|
|
990
|
+
if (this.state !== STATE.READY) {
|
|
990
991
|
return Promise.reject('subscribe_promise:: connection is not ready')
|
|
991
992
|
}
|
|
992
993
|
|
|
993
994
|
try {
|
|
994
|
-
let tagEncoded = encoder.encode(tag)
|
|
995
|
+
let tagEncoded = encoder.encode(tag)
|
|
995
996
|
this.send_enc_mode(
|
|
996
997
|
Buffer.concat([
|
|
997
998
|
MBP.NB('8', IOMsg.SUBSCRIBE_REQ),
|
|
@@ -1061,7 +1062,7 @@ export class IOCore extends EventEmitter {
|
|
|
1061
1062
|
}
|
|
1062
1063
|
this.on(tag, handler)
|
|
1063
1064
|
// do not subscribe now.
|
|
1064
|
-
// will subscribe when receive CID_RES
|
|
1065
|
+
// will subscribe when io state is 'ready'. (receive CID_RES from server)
|
|
1065
1066
|
|
|
1066
1067
|
}
|
|
1067
1068
|
|
|
@@ -1172,10 +1173,10 @@ export class IOCore extends EventEmitter {
|
|
|
1172
1173
|
*/
|
|
1173
1174
|
getStateName() {
|
|
1174
1175
|
//state <number>
|
|
1175
|
-
//value of constant
|
|
1176
|
-
//type of constant
|
|
1176
|
+
//value of constant STATE.NAME < number >
|
|
1177
|
+
//type of constant STATE.NAME name < string uppercase >
|
|
1177
1178
|
//stateName,eventName <string lowercase>
|
|
1178
|
-
return (
|
|
1179
|
+
return (STATE[this.state]).toLowerCase()
|
|
1179
1180
|
}
|
|
1180
1181
|
|
|
1181
1182
|
/**
|
|
@@ -1203,14 +1204,14 @@ export class IOCore extends EventEmitter {
|
|
|
1203
1204
|
* 보통 이벤트 이름과 동일하게 적거나 이벤트 상황 안내문을 넣는다.
|
|
1204
1205
|
*/
|
|
1205
1206
|
stateChange(state, emitEventAndMessage) {
|
|
1206
|
-
//
|
|
1207
|
+
// STATE constant name <string> upperCase
|
|
1207
1208
|
// eventName and .stateName <string> lowerCase
|
|
1208
1209
|
// .state <number>
|
|
1209
1210
|
// console.log('### stateChange reason:', emitEventAndMessage )
|
|
1210
1211
|
let eventName = state.toLowerCase()
|
|
1211
|
-
this.state =
|
|
1212
|
+
this.state = STATE[state.toUpperCase()] // state: number
|
|
1212
1213
|
|
|
1213
|
-
if (emitEventAndMessage){
|
|
1214
|
+
if (emitEventAndMessage) {
|
|
1214
1215
|
this.emit(eventName, emitEventAndMessage)
|
|
1215
1216
|
}
|
|
1216
1217
|
|
package/src/client/IOWS.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IOCore } from "./IOCore.js";
|
|
2
|
-
import {
|
|
2
|
+
import { SIZE_LIMIT } from "../common/constants.js";
|
|
3
3
|
import { WebSocket } from "ws";
|
|
4
4
|
|
|
5
5
|
// Node.js 'ws' websocket
|
|
@@ -24,19 +24,20 @@ export class IOWS extends IOCore {
|
|
|
24
24
|
super.close();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
keepAlive() {
|
|
27
|
+
keepConnection() {
|
|
29
28
|
if (!this.autoReconnect) return;
|
|
30
29
|
// Reconnect only if the socket is closed and the state reflects that.
|
|
31
|
-
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED)
|
|
30
|
+
if ((!this.socket || this.socket.readyState === WebSocket.CLOSED) ) {
|
|
32
31
|
this.open();
|
|
33
32
|
}
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
|
|
36
|
+
|
|
36
37
|
createConnection(url) {
|
|
37
38
|
// node WebSocket
|
|
38
39
|
this.socket = new WebSocket(url);
|
|
39
|
-
this.stateChange('
|
|
40
|
+
this.stateChange('connecting','connecting')
|
|
40
41
|
|
|
41
42
|
this.socket.onopen = () => {
|
|
42
43
|
this.socket.on('message', this.onWebSocketMessage.bind(this));
|
|
@@ -104,12 +104,12 @@ 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
|
+
keepConnection() {
|
|
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
114
|
}
|
|
115
115
|
}
|
|
@@ -126,7 +126,7 @@ export default class IO extends IOCore {
|
|
|
126
126
|
this.socket = new WebSocket(url);
|
|
127
127
|
this.socket.binaryType = IO.binaryType
|
|
128
128
|
|
|
129
|
-
this.stateChange('
|
|
129
|
+
this.stateChange('connecting','connecting')
|
|
130
130
|
|
|
131
131
|
this.socket.onopen = () => {
|
|
132
132
|
|
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
|
|
@@ -68,6 +56,7 @@ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
|
|
|
68
56
|
* @property {number} TAG_LEN1
|
|
69
57
|
* @property {number} TAG_LEN2
|
|
70
58
|
* @property {number} CONNECTION_CHECKER_PERIOD
|
|
59
|
+
* @property {number} CLIENT_PING_PERIOD
|
|
71
60
|
* @property {number} PROMISE_TIMEOUT
|
|
72
61
|
* @property {number} DID
|
|
73
62
|
* @property {number} CID
|
|
@@ -76,6 +65,7 @@ export const SIZE_LIMIT = {
|
|
|
76
65
|
TAG_LEN1: 255,
|
|
77
66
|
TAG_LEN2: 65535,
|
|
78
67
|
CONNECTION_CHECKER_PERIOD: 3000,
|
|
68
|
+
CLIENT_PING_PERIOD: 40000,
|
|
79
69
|
PROMISE_TIMEOUT: 5000,
|
|
80
70
|
DID: 8,
|
|
81
71
|
CID: 12
|
|
@@ -107,7 +97,7 @@ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
|
|
|
107
97
|
* @property {number} CID_REQ
|
|
108
98
|
* @property {number} CID_RES
|
|
109
99
|
* @property {number} QUOTA_LEVEL
|
|
110
|
-
* @property {number}
|
|
100
|
+
* @property {number} AUTH_CLEAR
|
|
111
101
|
* @property {number} SERVER_REDIRECT
|
|
112
102
|
* @property {number} LOOP
|
|
113
103
|
* @property {number} ECHO
|
|
@@ -165,9 +155,8 @@ export let IOMsg = {
|
|
|
165
155
|
CID_REQ: 0xC1,
|
|
166
156
|
CID_RES: 0xC2,
|
|
167
157
|
QUOTA_LEVEL: 0xC3,
|
|
168
|
-
|
|
158
|
+
AUTH_CLEAR: 0xC4,
|
|
169
159
|
SERVER_REDIRECT: 0xC5,
|
|
170
|
-
|
|
171
160
|
// ..
|
|
172
161
|
LOOP: 0xCB,
|
|
173
162
|
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
|
}
|