iosignal 0.0.1 → 1.0.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.
Files changed (47) hide show
  1. package/README.md +170 -0
  2. package/auth_file.json +13 -0
  3. package/auth_file.mjs +23 -0
  4. package/dist/iosignal.cjs +2 -0
  5. package/dist/iosignal.esm.js +3 -0
  6. package/dist/iosignal.esm.js.map +1 -0
  7. package/dist/iosignal.min.js +3 -0
  8. package/dist/iosignal.min.js.map +1 -0
  9. package/img/iosignal_stack.png +0 -0
  10. package/index.js +19 -0
  11. package/indexWebBrowser.js +13 -0
  12. package/package.json +48 -6
  13. package/rollup.config.js +69 -0
  14. package/src/api/RedisAPI.js +68 -0
  15. package/src/api/api_constant.js +7 -0
  16. package/src/api/api_reply.js +34 -0
  17. package/src/api/api_sudo.js +96 -0
  18. package/src/auth/Auth_Env.js +78 -0
  19. package/src/auth/Auth_File.js +75 -0
  20. package/src/auth/Auth_Redis.js +50 -0
  21. package/src/auth/BohoAuth.js +168 -0
  22. package/src/client/CongPacket.js +150 -0
  23. package/src/client/IOCongSocket.js +88 -0
  24. package/src/client/IOCore.js +959 -0
  25. package/src/client/IOWS.js +81 -0
  26. package/src/client/IOWebSocket.js +96 -0
  27. package/src/common/constants.js +159 -0
  28. package/src/common/quotaTable.js +61 -0
  29. package/src/common/util.js +61 -0
  30. package/src/server/FileLogger.js +30 -0
  31. package/src/server/Manager.js +521 -0
  32. package/src/server/Metric.js +154 -0
  33. package/src/server/Server.js +136 -0
  34. package/src/server/ServerRemote.js +235 -0
  35. package/src/server/ServerRemoteCore.js +467 -0
  36. package/src/server/serverOption.js +55 -0
  37. package/test-browser/favicon.ico +0 -0
  38. package/test-browser/index.html +93 -0
  39. package/test-browser/server.js +8 -0
  40. package/test-client-nodejs/client.cjs +17 -0
  41. package/test-client-nodejs/client.mjs +17 -0
  42. package/test-server/server-commonjs.cjs +8 -0
  43. package/test-server/server-esm.mjs +19 -0
  44. package/test-server/test-Auth_Env.js +17 -0
  45. package/test-server/test-Auth_File.js +9 -0
  46. package/test-server/test-api_reply.js +10 -0
  47. package/test-server/test-api_sudo.js +11 -0
@@ -0,0 +1,81 @@
1
+ import { IOCore } from "./IOCore.js";
2
+ import { WebSocket } from "ws";
3
+
4
+ // Node.js 'ws' websocket
5
+ export class IOWS extends IOCore{
6
+ constructor(url ) {
7
+ super(url);
8
+ if(url) this.open();
9
+ }
10
+
11
+
12
+
13
+ close() {
14
+ if(this.socket ){
15
+ this.socket.onclose = null
16
+ this.socket.onmessage = null
17
+ this.socket.onerror = null
18
+ this.socket.close();
19
+ this.socket = null;
20
+ }
21
+ this.emit('close')
22
+ }
23
+
24
+
25
+
26
+ stop() {
27
+ this.close()
28
+ clearInterval(this.connectionCheckerIntervalID);
29
+ this.connectionCheckerIntervalID = null
30
+ }
31
+
32
+ keepAlive() {
33
+ if ( !this.socket || this.socket?.readyState === 3 ) { //closed
34
+ this.open();
35
+ }
36
+ }
37
+
38
+
39
+ createConnection(url){
40
+ // node WebSocket
41
+ this.socket = new WebSocket ( url );
42
+ this.stateChange('opening')
43
+
44
+ this.socket.onopen = () => {
45
+ this.socket.on('message', this.onWebSocketMessage.bind(this) );
46
+ this.emit('open' );
47
+ };
48
+
49
+ this.socket.onerror = (e)=>{
50
+ this.emit('error', e)
51
+ }
52
+
53
+ this.socket.onclose = ()=>{
54
+ this.emit('close' );
55
+ }
56
+ }
57
+
58
+ onWebSocketMessage( data ) {
59
+ this.rxCounter++;
60
+ this.lastTxRxTime = Date.now();
61
+ this.rxBytes += data.byteLength
62
+ this.emit('socket_data', data );
63
+ }
64
+
65
+ socket_send(data) {
66
+ if( this.socket?.readyState === 1 ){ //open
67
+ // console.log('websocket send', data)
68
+ this.socket.send( data )
69
+ this.txCounter++;
70
+ this.txBytes += data.byteLength
71
+ this.lastTxRxTime = Date.now();
72
+ }else{
73
+ console.log('')
74
+ }
75
+ }
76
+
77
+ }
78
+
79
+
80
+
81
+
@@ -0,0 +1,96 @@
1
+ import { IOCore } from "./IOCore.js";
2
+ import { Buffer } from 'meta-buffer-pack'
3
+ export { Boho, RAND, BohoMsg, Meta, MetaSize , sha256, MBP, Buffer } from 'boho'
4
+ export * from '../common/constants.js'
5
+
6
+ // Browser WebSocket
7
+ export class IO extends IOCore{
8
+ constructor(url ) {
9
+ super(url);
10
+ document.addEventListener('visibilitychange', this.browserVisiblePing.bind(this));
11
+ if(url) this.open();
12
+ }
13
+
14
+ browserVisiblePing(){
15
+ if (document.visibilityState === 'visible') {
16
+ console.log('[Remote connection check] visibilityState is visible.')
17
+ this.ping()
18
+ }
19
+ }
20
+
21
+
22
+ close() {
23
+ if(this.socket ){
24
+ this.socket.onclose = null
25
+ this.socket.onmessage = null
26
+ this.socket.onerror = null
27
+ this.socket.close();
28
+ this.socket = null;
29
+ }
30
+ this.emit('close')
31
+ }
32
+
33
+
34
+ stop(){
35
+ this.close()
36
+ clearInterval(this.connectionCheckerIntervalID);
37
+ this.connectionCheckerIntervalID = null
38
+ }
39
+
40
+
41
+ keepAlive() {
42
+ if ( !this.socket || this.socket?.readyState === 3 ) { //closed
43
+ this.open();
44
+ }
45
+ }
46
+
47
+ createConnection(url){
48
+ // Web Browser WebSocket
49
+ this.socket = new WebSocket (url );
50
+ this.stateChange('opening')
51
+
52
+ this.socket.binaryType = "arraybuffer"
53
+ this.socket.onopen = () => {
54
+ this.socket.onmessage = this.onWebSocketMessage.bind(this) ;
55
+ this.emit('open' );
56
+ };
57
+
58
+ this.socket.onerror = (e)=>{
59
+ this.emit('error', e)
60
+ }
61
+
62
+ this.socket.onclose = ()=>{
63
+ this.emit('close' );
64
+ }
65
+ }
66
+
67
+ onWebSocketMessage( event ) {
68
+ this.rxCounter++;
69
+ this.lastTxRxTime = Date.now();
70
+ let buffer;
71
+
72
+ // if( event.data instanceof ArrayBuffer ){
73
+ // //binary frame
74
+ // }else{
75
+ // //text frame
76
+ // }
77
+ buffer = Buffer.from( event.data )
78
+ this.rxBytes += buffer.byteLength
79
+
80
+ this.emit('socket_data', buffer );
81
+ }
82
+
83
+ socket_send(data) {
84
+ if( this.socket?.readyState === 1 ){ //open
85
+ // console.log('websocket send', data)
86
+ this.socket.send( data )
87
+ this.txCounter++;
88
+ this.txBytes += data.byteLength
89
+ this.lastTxRxTime = Date.now();
90
+ }else{
91
+ console.log('.')
92
+ }
93
+ }
94
+
95
+ }
96
+
@@ -0,0 +1,159 @@
1
+
2
+ // IOclient state
3
+ export const STATES = {
4
+ OPENING: 0,
5
+ OPEN: 1,
6
+ CLOSING: 2,
7
+ CLOSED: 3,
8
+ SERVER_READY: 4,
9
+ AUTH_FAIL: 5,
10
+ AUTH_READY: 6,
11
+ READY: 7,
12
+ REDIRECTING: 8
13
+ }
14
+ for (let c in STATES) { STATES[STATES[c]] = c }
15
+
16
+ // server side client state
17
+ export const CLIENT_STATE = {
18
+ INIT: 0,
19
+ SENT_SERVER_READY: 1,
20
+ RECV_AUTH_REQ: 2,
21
+ SENT_SERVER_NONCE: 3,
22
+ RECV_AUTH_HMAC: 4,
23
+ AUTH_FAIL: 5,
24
+ AUTH_READY: 6,
25
+ CID_READY: 7
26
+ }
27
+ for (let c in CLIENT_STATE) { CLIENT_STATE[CLIENT_STATE[c]] = c }
28
+
29
+ export let ENC_MODE = {
30
+ NO: 0,
31
+ YES: 1,
32
+ AUTO: 2
33
+ }
34
+
35
+ for (let c in ENC_MODE) { ENC_MODE[ENC_MODE[c]] = c }
36
+
37
+
38
+ export const SIZE_LIMIT = {
39
+ TAG_LEN1: 255,
40
+ TAG_LEN2: 65535,
41
+ CONNECTION_CHECKER_PERIOD: 3000,
42
+ PROMISE_TIMEOUT: 5000,
43
+ DID: 8,
44
+ CID: 12
45
+ }
46
+
47
+ export let PAYLOAD_TYPE = {
48
+ EMPTY: 0,
49
+ TEXT: 1,
50
+ BINARY: 2,
51
+ OBJECT: 3, // one stringify able object. no buffer.
52
+ MJSON: 4, // multiple stringify able obejct. JSON string. with top levle array , no buffer
53
+ MBA: 5 // "meta_buffer_arguments" arbitary types. buffer included.
54
+ }
55
+ for (let c in PAYLOAD_TYPE) { PAYLOAD_TYPE[PAYLOAD_TYPE[c]] = c }
56
+ // console.log( PAYLOAD_TYPE )
57
+
58
+ // MJSON: multiple arguments
59
+ // accepet only string, number, root depth js primittive object,
60
+ // unpack and will send to receiver handler with multiple params.
61
+
62
+ // MBA: buffer pack of multiple arguments. check "meta-buffer-pack" module.
63
+ // MBA: when armuents includes raw Buffer( TypedArray )
64
+
65
+ // IO message pack one byte header.
66
+ export let IOMsg = {
67
+
68
+ /*
69
+ * 0~127dec. reserved. for text stream.
70
+ * 0~31: control code
71
+ * 32~126: ascii charactor
72
+ * 127: DEL
73
+ */
74
+
75
+ // ADMIN_REQ: 0xA0,
76
+
77
+ // DO NOT USE: 0xB0~ 0xBF
78
+ // Boho module using this numbers.
79
+ // AUTH_REQ : 0xB0,
80
+ // AUTH_NONCE: 0xB1,
81
+ // AUTH_HMAC: 0xB2,
82
+ // AUTH_ACK: 0xB3,
83
+ // AUTH_FAIL: 0xB4,
84
+ // AUTH_EXT: 0xB5,
85
+ // ENC_PACK : 0xB6,
86
+ // ENC_E2E : 0xB7,
87
+ // ENC_488 : 0xB8
88
+ // reserved ~0xBF
89
+
90
+ // C. IO status contorl.
91
+ SERVER_READY: 0xC0,
92
+ CID_REQ: 0xC1,
93
+ CID_RES: 0xC2,
94
+ QUOTA_LEVEL: 0xC3,
95
+ SERVER_CLEAR_AUTH: 0xC4,
96
+ SERVER_REDIRECT: 0xC5,
97
+
98
+ // ..
99
+ LOOP: 0xCB,
100
+ ECHO: 0xCC,
101
+ PING: 0xCD,
102
+ PONG: 0xCE,
103
+ CLOSE: 0xCF,
104
+ // ~CF
105
+
106
+
107
+ // D. IO data signaling
108
+ SIGNAL: 0xD0,
109
+ SIGNAL_REQ: 0xD1,
110
+ SIGNAL_E2E: 0xD2,
111
+ SUBSCRIBE: 0xD3,
112
+ SUBSCRIBE_REQ: 0xD4,
113
+ UNSUBSCRIBE: 0xD5,
114
+ SERVER_SIGNAL: 0xD6,
115
+
116
+ // ..
117
+ IAM: 0xD9,
118
+ IAM_RES: 0xDA,
119
+
120
+ //..
121
+ SET: 0xDB, //
122
+ RESPONSE_CODE: 0xDC,
123
+ RESPONSE_MBP: 0xDD,
124
+
125
+ REQUEST: 0xDE, //client public
126
+ RESPONSE: 0xDF,
127
+ // ~DF
128
+
129
+
130
+ // F. Framing Flow control related framing protocol.(CongPacket)
131
+ FLOW_MODE: 0xF0,
132
+ WAIT: 0xF1,
133
+ RESUME: 0xF2,
134
+ //..
135
+ TIME_OUT: 0xFD,
136
+ OVER_SIZE: 0xFE,
137
+ OVER_FLOW: 0xFF
138
+
139
+ }
140
+
141
+ for (let c in IOMsg) { IOMsg[IOMsg[c]] = c }
142
+
143
+ // console.log( IOMsg );
144
+
145
+
146
+ export const API_TYPE = {
147
+ 'REQUEST_RESPONSE': 'requet_response',
148
+ 'ONE_WAY': 'one_way'
149
+ }
150
+
151
+
152
+
153
+ // api response status code
154
+ export const STATUS = {
155
+ OK: 0,
156
+ //0~127: success
157
+ //128~255: fail
158
+ ERROR: 255
159
+ }
@@ -0,0 +1,61 @@
1
+ // table index related with:
2
+ // - AUTH database level
3
+ // - serverOption.defaultQuotaIndex
4
+
5
+ // quota example
6
+ // index range: 0~255.
7
+ export let quotaTable = {
8
+ // CongSocket
9
+ 0: { // default. anonymouse:
10
+ signalSize: 1500,
11
+ publishCounter: 10,
12
+ trafficRate: 10000
13
+ },
14
+ 1: { // auth_ultralight: eg. Arduino Uno.
15
+ signalSize: 255,
16
+ publishCounter: 10,
17
+ trafficRate: 100000
18
+ },
19
+ 2: { // auth_light: eg. authorized ESP.
20
+ signalSize: 65535,
21
+ publishCounter: 10,
22
+ trafficRate: 1048576
23
+ },
24
+
25
+ // WebSocket (browser and node app)
26
+ 3: { // authorized basic.
27
+ signalSize: 1048576,
28
+ publishCounter: 10,
29
+ trafficRate: 1048576 * 20
30
+ },
31
+
32
+ // WebSocket (browser and node app)
33
+ 10: { // anonymouse
34
+ signalSize: 1500,
35
+ publishCounter: 5,
36
+ trafficRate: 1048576 * 20
37
+ },
38
+
39
+ 11: { // authorized basic.
40
+ signalSize: 65535,
41
+ publishCounter: 10,
42
+ trafficRate: 1048576 * 20
43
+ },
44
+
45
+ 12: { // authorized power.
46
+ signalSize: 1048576,
47
+ publishCounter: 100,
48
+ trafficRate: 1048576 * 20
49
+ },
50
+
51
+ // you can add your custom quota level.
52
+
53
+ // super admin or root user.
54
+ // to monitor, metric, sudo command, db acess
55
+ 255: {
56
+ signalSize: 1048576 * 20,
57
+ publishCounter: 10000,
58
+ trafficRate: 1048576 * 100
59
+ }
60
+ }
61
+
@@ -0,0 +1,61 @@
1
+ import { networkInterfaces } from 'os';
2
+
3
+ export function isPrivateIP(ip){
4
+ if(ip.indexOf("0.0.0.0") === 0) return true
5
+ if(ip.indexOf("127.0.0.1") === 0) return true
6
+ if(ip.indexOf("192.168.") === 0) return true
7
+ if(ip.indexOf("10.") === 0) return true
8
+ if(ip.indexOf("172.") === 0){
9
+ if(ip.indexOf("172.16.") === 0) return true
10
+ if(ip.indexOf("172.17.") === 0) return true
11
+ if(ip.indexOf("172.18.") === 0) return true
12
+ if(ip.indexOf("172.19.") === 0) return true
13
+ if(ip.indexOf("172.20.") === 0) return true
14
+ if(ip.indexOf("172.21.") === 0) return true
15
+ if(ip.indexOf("172.22.") === 0) return true
16
+ if(ip.indexOf("172.23.") === 0) return true
17
+ if(ip.indexOf("172.24.") === 0) return true
18
+ if(ip.indexOf("172.25.") === 0) return true
19
+ if(ip.indexOf("172.26.") === 0) return true
20
+ if(ip.indexOf("172.27.") === 0) return true
21
+ if(ip.indexOf("172.28.") === 0) return true
22
+ if(ip.indexOf("172.29.") === 0) return true
23
+ if(ip.indexOf("172.30.") === 0) return true
24
+ if(ip.indexOf("172.31.") === 0) return true
25
+ }
26
+
27
+ return false
28
+ }
29
+
30
+ export function numberWithCommas (x) {
31
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
32
+ }
33
+
34
+ export function getIPv4HexString(ipStr){
35
+ let ipv4 = ipStr.split('.')
36
+ return Buffer.from(ipv4).toString('hex')
37
+ }
38
+
39
+ export function getLocalAddress(){
40
+ const nets = networkInterfaces();
41
+ // console.log(nets)
42
+ const results = Object.create(null); // Or just '{}', an empty object
43
+ let localAddress =''
44
+ for (const name of Object.keys(nets)) {
45
+ for (const net of nets[name]) {
46
+ // Skip over non-IPv4 and internal (i.e. 127.0.0.1) addresses
47
+ // 'IPv4' is in Node <= 17, from 18 it's a number 4 or 6
48
+ const familyV4Value = typeof net.family === 'string' ? 'IPv4' : 4
49
+ if (net.family === familyV4Value && !net.internal) {
50
+ if (!results[name]) {
51
+ results[name] = [];
52
+ }
53
+ results[name].push(net.address);
54
+ localAddress = net.address
55
+ }
56
+ }
57
+ }
58
+
59
+ // console.log('localAddress:', localAddress)
60
+ return localAddress
61
+ }
@@ -0,0 +1,30 @@
1
+ import fs from 'fs'
2
+
3
+ const formatter = new Intl.DateTimeFormat('ko-KR', {
4
+ // hour12: true,
5
+ // hour: 'numeric',
6
+ // minute: '2-digit',
7
+ // second: '2-digit'
8
+ year: 'numeric', month: 'numeric', day: 'numeric',
9
+ hour: 'numeric', minute: 'numeric',
10
+ hour12: false,
11
+ timeZone: 'Asia/Seoul'
12
+ });
13
+
14
+
15
+ export class FileLogger{
16
+ constructor(path ){
17
+ this.file = fs.openSync(path ,'a+')
18
+ console.log('new logFile', path, this.file )
19
+ }
20
+
21
+ log(msg){
22
+ let format =formatter.format(new Date()) + " "+ msg +'\n';
23
+ fs.write( this.file, format , (err) => {
24
+ if (err) throw err;
25
+ })
26
+
27
+ }
28
+
29
+
30
+ }