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.
- package/README.md +170 -0
- package/auth_file.json +13 -0
- package/auth_file.mjs +23 -0
- package/dist/iosignal.cjs +2 -0
- package/dist/iosignal.esm.js +3 -0
- package/dist/iosignal.esm.js.map +1 -0
- package/dist/iosignal.min.js +3 -0
- package/dist/iosignal.min.js.map +1 -0
- package/img/iosignal_stack.png +0 -0
- package/index.js +19 -0
- package/indexWebBrowser.js +13 -0
- package/package.json +48 -6
- package/rollup.config.js +69 -0
- package/src/api/RedisAPI.js +68 -0
- package/src/api/api_constant.js +7 -0
- package/src/api/api_reply.js +34 -0
- package/src/api/api_sudo.js +96 -0
- package/src/auth/Auth_Env.js +78 -0
- package/src/auth/Auth_File.js +75 -0
- package/src/auth/Auth_Redis.js +50 -0
- package/src/auth/BohoAuth.js +168 -0
- package/src/client/CongPacket.js +150 -0
- package/src/client/IOCongSocket.js +88 -0
- package/src/client/IOCore.js +959 -0
- package/src/client/IOWS.js +81 -0
- package/src/client/IOWebSocket.js +96 -0
- package/src/common/constants.js +159 -0
- package/src/common/quotaTable.js +61 -0
- package/src/common/util.js +61 -0
- package/src/server/FileLogger.js +30 -0
- package/src/server/Manager.js +521 -0
- package/src/server/Metric.js +154 -0
- package/src/server/Server.js +136 -0
- package/src/server/ServerRemote.js +235 -0
- package/src/server/ServerRemoteCore.js +467 -0
- package/src/server/serverOption.js +55 -0
- package/test-browser/favicon.ico +0 -0
- package/test-browser/index.html +93 -0
- package/test-browser/server.js +8 -0
- package/test-client-nodejs/client.cjs +17 -0
- package/test-client-nodejs/client.mjs +17 -0
- package/test-server/server-commonjs.cjs +8 -0
- package/test-server/server-esm.mjs +19 -0
- package/test-server/test-Auth_Env.js +17 -0
- package/test-server/test-Auth_File.js +9 -0
- package/test-server/test-api_reply.js +10 -0
- package/test-server/test-api_sudo.js +11 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
import { webcrypto } from 'crypto';
|
|
2
|
+
import { MBP } from 'meta-buffer-pack'
|
|
3
|
+
import { Boho, BohoMsg, MetaSize } from 'boho'
|
|
4
|
+
import { serverOption } from './serverOption.js';
|
|
5
|
+
import { IOMsg, ENC_MODE, CLIENT_STATE } from '../common/constants.js'
|
|
6
|
+
import { quotaTable } from '../common/quotaTable.js'
|
|
7
|
+
|
|
8
|
+
const decoder = new TextDecoder()
|
|
9
|
+
|
|
10
|
+
const NB = MBP.NB
|
|
11
|
+
const MB = MBP.MB
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
export class ServerRemoteCore {
|
|
15
|
+
constructor(socket, manager) {
|
|
16
|
+
|
|
17
|
+
this.socket = socket;
|
|
18
|
+
socket.isAlive = true;
|
|
19
|
+
socket.txCounter = 0;
|
|
20
|
+
socket.rxCounter = 0;
|
|
21
|
+
socket.openTime = Date.now()
|
|
22
|
+
|
|
23
|
+
this.boho = new Boho()
|
|
24
|
+
this.encMode = ENC_MODE.AUTO;
|
|
25
|
+
this.channels = new Set(); // subscribed tags
|
|
26
|
+
this.retain_signal = new Map();
|
|
27
|
+
|
|
28
|
+
this.ssid = ServerRemoteCore.ssid++; // ordered index number
|
|
29
|
+
this.manager = manager;
|
|
30
|
+
|
|
31
|
+
this.cid; // Communication Id
|
|
32
|
+
this.did; // Device Id
|
|
33
|
+
this.uid;
|
|
34
|
+
this.nick = ""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
this.lastEchoMessage = "N"
|
|
38
|
+
this.privateNode = false
|
|
39
|
+
this.HOME_CHANNEL = ""
|
|
40
|
+
this.level = serverOption.defaultQuotaIndex;
|
|
41
|
+
this.quota = quotaTable[this.level];
|
|
42
|
+
this.isAdmin = false;
|
|
43
|
+
|
|
44
|
+
this.state;
|
|
45
|
+
this.stateLog = [];
|
|
46
|
+
this.setState(CLIENT_STATE.INIT)
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static ssid = 1;
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
setState(state) {
|
|
55
|
+
this.state = state
|
|
56
|
+
if (serverOption.debug.showAuthInfo) {
|
|
57
|
+
this.stateLog.push(state)
|
|
58
|
+
console.log(this.stateLog.join('>'))
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getState(){
|
|
63
|
+
return this.state
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getStateName(){
|
|
67
|
+
//state <number>
|
|
68
|
+
//value of constant STATES.NAME < number >
|
|
69
|
+
//type of constant STATES.NAME name < string uppercase >
|
|
70
|
+
//stateName,eventName <string lowercase>
|
|
71
|
+
return ( CLIENT_STATE[ this.state ]).toLowerCase()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
showMessageLog(message, isBinary) {
|
|
76
|
+
let from = this.boho.isAuthorized ? ` id: ${this.did}(${this.cid})` : ""
|
|
77
|
+
if (isBinary) {
|
|
78
|
+
let msgTypeName = IOMsg[message[0]]
|
|
79
|
+
if (!msgTypeName) msgTypeName = BohoMsg[message[0]]
|
|
80
|
+
msgTypeName = '#' + this.ssid + '(' + this.cid + ') [ ' + msgTypeName + ' ]';
|
|
81
|
+
if (message.byteLength > 40) {
|
|
82
|
+
console.log(msgTypeName + from + ' LEN:', message.length);
|
|
83
|
+
} else {
|
|
84
|
+
console.log(msgTypeName + from, message);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
} else {
|
|
88
|
+
console.log(from + '[TEXT MSG] %s', message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
rxQuotaChecker(message) {
|
|
93
|
+
let rxBytes = message.byteLength
|
|
94
|
+
this.manager.rxBytes += rxBytes;
|
|
95
|
+
|
|
96
|
+
if (serverOption.useQuota.signalSize && (rxBytes > this.quota.signalSize)) {
|
|
97
|
+
console.log('## quota: size over')
|
|
98
|
+
this.send(Buffer.from([IOMsg.OVER_SIZE]))
|
|
99
|
+
if (serverOption.useQuota.disconnect) this.close();
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// todo:
|
|
104
|
+
// traffic rate :
|
|
105
|
+
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//
|
|
110
|
+
onTimeDelayMessage(message, isBinary = true) {
|
|
111
|
+
setTimeout(() => {
|
|
112
|
+
this.onSocketMessage(message, isBinary)
|
|
113
|
+
}
|
|
114
|
+
, serverOption.debug.delay)
|
|
115
|
+
}
|
|
116
|
+
// CongSocket or WebSocket
|
|
117
|
+
onSocketMessage(message, isBinary = true) {
|
|
118
|
+
|
|
119
|
+
this.receiveMonitor() // rx data and ping pong : timeout check
|
|
120
|
+
if (!this.rxQuotaChecker(message)) return
|
|
121
|
+
|
|
122
|
+
if (serverOption.showMessage === 'message') this.showMessageLog(message, isBinary)
|
|
123
|
+
|
|
124
|
+
let msgType, decoded
|
|
125
|
+
|
|
126
|
+
if (isBinary) {
|
|
127
|
+
msgType = message[0]
|
|
128
|
+
|
|
129
|
+
if (msgType === BohoMsg.ENC_488) {
|
|
130
|
+
// let from = this.boho.isAuthorized ? this.cid : "anonymous"
|
|
131
|
+
// console.log(`>> [E488] from: ${from} LEN ${message.byteLength}`)
|
|
132
|
+
// console.log( "ENC buffer", message)
|
|
133
|
+
try {
|
|
134
|
+
decoded = this.boho.decrypt_488(message)
|
|
135
|
+
} catch (err) {
|
|
136
|
+
console.log('-- E488 DEC_FAIL', err)
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (decoded) {
|
|
141
|
+
msgType = decoded[0]
|
|
142
|
+
message = decoded // signal message
|
|
143
|
+
// console.log('[D]', IOMsg[ msgType] )
|
|
144
|
+
} else {
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
} else if (msgType === BohoMsg.ENC_E2E) { // End to End Signal
|
|
149
|
+
try {
|
|
150
|
+
decoded = this.boho.decrypt_488(message)
|
|
151
|
+
} catch (err) {
|
|
152
|
+
console.log('-- E2E DEC_FAIL', err)
|
|
153
|
+
return
|
|
154
|
+
}
|
|
155
|
+
// console.log('e2e unpack:', decoded )
|
|
156
|
+
if (decoded) {
|
|
157
|
+
msgType = decoded[0]
|
|
158
|
+
message.set(decoded, MetaSize.ENC_488) // set decoded signal_e2e headaer.
|
|
159
|
+
message = message.subarray(MetaSize.ENC_488) // reset offset.
|
|
160
|
+
// console.log('[D]', IOMsg[ msgType] )
|
|
161
|
+
} else {
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
} else {
|
|
166
|
+
// console.log( `[P] ${ IOMsg[ msgType] || BohoMsg[cmd]} LEN: ${message.byteLength}` )
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
switch (msgType) {
|
|
170
|
+
case IOMsg.PING:
|
|
171
|
+
// console.log('-- ping from:' , this.cid )
|
|
172
|
+
this.pong();
|
|
173
|
+
break;
|
|
174
|
+
|
|
175
|
+
case IOMsg.PONG:
|
|
176
|
+
// console.log('<-pong')
|
|
177
|
+
break;
|
|
178
|
+
|
|
179
|
+
case IOMsg.CID_REQ:
|
|
180
|
+
if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
|
|
181
|
+
// console.log('protocol error. cid_req before server_ready')
|
|
182
|
+
this.close()
|
|
183
|
+
}
|
|
184
|
+
if (!this.cid) {
|
|
185
|
+
this.cid = '?' + webcrypto.getRandomValues(Buffer.alloc(3)).toString('base64url')
|
|
186
|
+
this.manager.cid2remote.set(this.cid, this)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// console.log('<< SENDING CID_RES:', this.cid)
|
|
190
|
+
this.send_enc_mode(MBP.pack(
|
|
191
|
+
MB('#cid_ack', '8', IOMsg.CID_RES),
|
|
192
|
+
MB('#cid', this.cid)
|
|
193
|
+
))
|
|
194
|
+
|
|
195
|
+
this.setState(CLIENT_STATE.CID_READY)
|
|
196
|
+
break;
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
case IOMsg.ECHO: // TEXT only
|
|
200
|
+
try {
|
|
201
|
+
let msg = decoder.decode(message.subarray(1))
|
|
202
|
+
this.lastEchoMessage = msg
|
|
203
|
+
} catch (error) {
|
|
204
|
+
// console.log('ECHO message is not a text')
|
|
205
|
+
}
|
|
206
|
+
this.send(message, isBinary)
|
|
207
|
+
break;
|
|
208
|
+
|
|
209
|
+
case IOMsg.IAM: // iam
|
|
210
|
+
if(message.byteLength > 1){
|
|
211
|
+
let iamInfo = message.subarray(1)
|
|
212
|
+
this.nick = decoder.decode(iamInfo)
|
|
213
|
+
console.log('iam nick reset', this.nick)
|
|
214
|
+
}
|
|
215
|
+
this.iamResponse()
|
|
216
|
+
break;
|
|
217
|
+
|
|
218
|
+
case IOMsg.SIGNAL_E2E:
|
|
219
|
+
case IOMsg.SIGNAL:
|
|
220
|
+
if (message.byteLength >= 3) {
|
|
221
|
+
let tagLen = message.readUInt8(1)
|
|
222
|
+
if (message.byteLength >= tagLen + 2) {
|
|
223
|
+
let tag = message.subarray(2, 2 + tagLen)
|
|
224
|
+
tag = decoder.decode(tag)
|
|
225
|
+
this.manager.sender(tag, this, message )
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
break;
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
case IOMsg.UNSUBSCRIBE:
|
|
233
|
+
if (message.byteLength == 2) {
|
|
234
|
+
this.manager.unsubscribe([""], this)
|
|
235
|
+
} else if (message.byteLength >= 3) {
|
|
236
|
+
let tagLen = message.readUInt8(1)
|
|
237
|
+
|
|
238
|
+
if (message.byteLength == tagLen + 2) {
|
|
239
|
+
let tag = message.subarray(2, 2 + tagLen)
|
|
240
|
+
tag = decoder.decode(tag)
|
|
241
|
+
// console.log('unsub: tag', tag)
|
|
242
|
+
let tagList = tag.split(',')
|
|
243
|
+
this.manager.unsubscribe(tagList, this)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
case IOMsg.SUBSCRIBE: // 1byte tagLen
|
|
250
|
+
if (message.byteLength >= 3) {
|
|
251
|
+
let tagLen = message.readUInt8(1)
|
|
252
|
+
if (message.byteLength == tagLen + 2) {
|
|
253
|
+
let tag = message.subarray(2, 2 + tagLen)
|
|
254
|
+
tag = decoder.decode(tag)
|
|
255
|
+
let tagList = tag.split(',')
|
|
256
|
+
// console.log('-- SUBSCRIBE req splittagList', tagList)
|
|
257
|
+
this.manager.subscribe(tagList, this)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
|
|
262
|
+
case IOMsg.SUBSCRIBE_REQ: // 2bytes tagLen
|
|
263
|
+
// console.log('#####recv sub_req ', message, message.byteLength )
|
|
264
|
+
if (message.byteLength >= 6) {
|
|
265
|
+
let msgID = message.readUInt16BE(1)
|
|
266
|
+
let tagLen = message.readUInt16BE(3)
|
|
267
|
+
if (message.byteLength == tagLen + 5) {
|
|
268
|
+
let tag = message.subarray(5, 5 + tagLen)
|
|
269
|
+
tag = decoder.decode(tag)
|
|
270
|
+
let tagList = tag.split(',')
|
|
271
|
+
// console.log('>> SUBSCRIBE_REQ from:', this.cid, tagList)
|
|
272
|
+
let size = this.manager.subscribe(tagList, this)
|
|
273
|
+
|
|
274
|
+
// this.response(msgID, 0, { size: size })
|
|
275
|
+
this.response(msgID, 0)
|
|
276
|
+
} else {
|
|
277
|
+
this.response(msgID, 255 )
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
break;
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
case IOMsg.REQUEST: //api request
|
|
284
|
+
try {
|
|
285
|
+
let req = MBP.unpack( message )
|
|
286
|
+
// console.log('request unpack req', req)
|
|
287
|
+
if(req){
|
|
288
|
+
// console.log('request target:', req.target, 'topic:', req.topic)
|
|
289
|
+
if( !req.target || !req.topic ) return
|
|
290
|
+
if(this.manager.server.apiNames.has(req.target)){
|
|
291
|
+
this.manager.server.emit( req.target, this , req )
|
|
292
|
+
}else{
|
|
293
|
+
console.log('UnKnown API req: ', req.target)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
} catch (e) {
|
|
297
|
+
console.log('request catch error', e)
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
case IOMsg.CLOSE:
|
|
303
|
+
if (message.byteLength > 1) {
|
|
304
|
+
let reason = decoder.decode(message.subarray(1))
|
|
305
|
+
console.log('>> CLOSE reason:', reason)
|
|
306
|
+
this.close();
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
// Auth
|
|
312
|
+
case BohoMsg.AUTH_REQ:
|
|
313
|
+
if (!this.manager.authManager) return
|
|
314
|
+
if (this.state < CLIENT_STATE.SENT_SERVER_READY) {
|
|
315
|
+
// console.log('protocol error. auth_req before server_ready')
|
|
316
|
+
this.close();
|
|
317
|
+
}
|
|
318
|
+
this.setState(CLIENT_STATE.RECV_AUTH_REQ)
|
|
319
|
+
let auth_nonce_pack = this.boho.auth_nonce()
|
|
320
|
+
// console.log('## auth_nonce_pack', auth_nonce_pack )
|
|
321
|
+
this.send(auth_nonce_pack)
|
|
322
|
+
this.setState(CLIENT_STATE.SENT_SERVER_NONCE)
|
|
323
|
+
break;
|
|
324
|
+
|
|
325
|
+
case BohoMsg.AUTH_HMAC:
|
|
326
|
+
if (!this.manager.authManager) return
|
|
327
|
+
if (this.state < CLIENT_STATE.SENT_SERVER_NONCE) {
|
|
328
|
+
// console.log('protocol error. auth_hmac before server_nonce')
|
|
329
|
+
this.close();
|
|
330
|
+
}
|
|
331
|
+
this.setState(CLIENT_STATE.RECV_AUTH_HMAC)
|
|
332
|
+
//async
|
|
333
|
+
this.manager.authManager.verify_auth_hmac(message, this)
|
|
334
|
+
.then(authInfo=>{
|
|
335
|
+
if(authInfo){
|
|
336
|
+
this.manager.deligateSignal(remote, '@$name', authInfo.name)
|
|
337
|
+
// console.log('device login success authInfo', authInfo)
|
|
338
|
+
// this.manager.sender('@$name', authInfo.name )
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
})
|
|
342
|
+
.catch(e=>{
|
|
343
|
+
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
return;
|
|
347
|
+
|
|
348
|
+
default:
|
|
349
|
+
// console.log('unknown MsgType:',msgType,' from:', this.ip, this.ssid, this.cid )
|
|
350
|
+
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
} else {
|
|
354
|
+
// TEXT FRAME
|
|
355
|
+
try {
|
|
356
|
+
let textMessage = decoder.decode(message)
|
|
357
|
+
// console.log('text buffer:',textMessage )
|
|
358
|
+
// console.log('text buffer:',message.toString('hex') )
|
|
359
|
+
this.manager.server.emit('text_message', textMessage, this)
|
|
360
|
+
} catch (error) {
|
|
361
|
+
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
response(msgId, statusCode, body) {
|
|
369
|
+
// console.log('response body', body)
|
|
370
|
+
if( body ){
|
|
371
|
+
|
|
372
|
+
this.send_enc_mode( MBP.pack(
|
|
373
|
+
MB('#type', '8', IOMsg.RESPONSE_MBP),
|
|
374
|
+
MB('status','8', statusCode),
|
|
375
|
+
MB('mid','16', msgId),
|
|
376
|
+
MB('body',body)
|
|
377
|
+
))
|
|
378
|
+
|
|
379
|
+
}else{
|
|
380
|
+
this.send_enc_mode( MBP.pack(
|
|
381
|
+
MB('#type','8', IOMsg.RESPONSE_MBP),
|
|
382
|
+
MB('status','8', statusCode),
|
|
383
|
+
MB('mid','16', msgId)
|
|
384
|
+
))
|
|
385
|
+
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
send_enc_mode(data, useEncryption = false) {
|
|
392
|
+
|
|
393
|
+
if (this.encMode === ENC_MODE.YES ||
|
|
394
|
+
this.encMode === ENC_MODE.AUTO &&
|
|
395
|
+
!this.TLS && this.boho.isAuthorized
|
|
396
|
+
) useEncryption = true;
|
|
397
|
+
|
|
398
|
+
// console.log('svr useEnc', useEncryption, data )
|
|
399
|
+
|
|
400
|
+
if (useEncryption && data[0] == IOMsg.SIGNAL_E2E) {
|
|
401
|
+
// E2E는,
|
|
402
|
+
// 서버는 수신자와 암호통신하는경우, 헤더부분만 암호화 하고, 데이타 부분은 그대로 전달해야한다.
|
|
403
|
+
let tagLen = data[1];
|
|
404
|
+
|
|
405
|
+
// let tagInfo = decoder.decode( data.subarray( 2, 2 + tagLen) )
|
|
406
|
+
// console.log('server bypass E2E signal taginfo:', tagInfo )
|
|
407
|
+
|
|
408
|
+
let encHeader = this.boho.encrypt_488(data.subarray(0, 3 + tagLen))
|
|
409
|
+
// console.log('size check:', encHeader.byteLength == (tagLen + 3 + 21 ) )
|
|
410
|
+
encHeader[0] = BohoMsg.ENC_E2E
|
|
411
|
+
// encHeader 크기가 21(enc_488)크기 만큼 커짐. tagLen+3 + 21
|
|
412
|
+
let newEncBuffer = Buffer.concat([encHeader, data.subarray(3 + tagLen)])
|
|
413
|
+
|
|
414
|
+
// console.log('ENC_E2E', newEncBuffer)
|
|
415
|
+
this.send(newEncBuffer)
|
|
416
|
+
|
|
417
|
+
} else if (useEncryption) {
|
|
418
|
+
let encPack = this.boho.encrypt_488(data)
|
|
419
|
+
if (encPack) {
|
|
420
|
+
// console.log('send *S* LEN:', encPack.byteLength)
|
|
421
|
+
this.send(encPack)
|
|
422
|
+
} else {
|
|
423
|
+
console.log('encryption FAIL: NO DATA TRANSIT')
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
// console.log('send -N-')
|
|
427
|
+
this.send(data)
|
|
428
|
+
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
iamResponse(info = "") {
|
|
436
|
+
|
|
437
|
+
if (info == "") {
|
|
438
|
+
//send general info
|
|
439
|
+
let channels = []
|
|
440
|
+
for (let tag of this.channels.keys()) {
|
|
441
|
+
channels.push(tag)
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
info = {
|
|
445
|
+
"ssid": this.ssid,
|
|
446
|
+
"uid": this.uid,
|
|
447
|
+
"cid": this.cid,
|
|
448
|
+
"did": this.did,
|
|
449
|
+
"nick": this.nick,
|
|
450
|
+
"ip": this.ip
|
|
451
|
+
, 'tag': channels
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
let pack = MBP.pack(
|
|
456
|
+
MB('#MsgType', '8', IOMsg.IAM_RES),
|
|
457
|
+
MB('#info', info)
|
|
458
|
+
)
|
|
459
|
+
this.send_enc_mode(pack)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// storeSet(topic, ...args){
|
|
463
|
+
// this.manager.set( this, topic, ...args )
|
|
464
|
+
// }
|
|
465
|
+
|
|
466
|
+
}
|
|
467
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
export let serverOption = {
|
|
4
|
+
clientTracking: false,
|
|
5
|
+
port: 7777,
|
|
6
|
+
congPort: null,
|
|
7
|
+
timeout: 50000,
|
|
8
|
+
showMessage: 'none',
|
|
9
|
+
showMetric: 0,
|
|
10
|
+
showChannel: 0,
|
|
11
|
+
monitorPeriod: 5000,
|
|
12
|
+
fileLogger:{
|
|
13
|
+
connection: {
|
|
14
|
+
use: false,
|
|
15
|
+
path: 'connection.log'
|
|
16
|
+
},
|
|
17
|
+
auth: {
|
|
18
|
+
use: false,
|
|
19
|
+
path: 'auth.log'
|
|
20
|
+
},
|
|
21
|
+
attack:{
|
|
22
|
+
use: false,
|
|
23
|
+
path:'attack.log'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
useQuota:{
|
|
27
|
+
signalSize: false,
|
|
28
|
+
publishCounter: false,
|
|
29
|
+
trafficRate: false,
|
|
30
|
+
disconnect: false
|
|
31
|
+
},
|
|
32
|
+
defaultQuotaIndex: 0,
|
|
33
|
+
adminLevel: 255,
|
|
34
|
+
|
|
35
|
+
debug:{
|
|
36
|
+
slow: false,
|
|
37
|
+
delay: 500,
|
|
38
|
+
showAuthInfo: false
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
retain:{
|
|
42
|
+
isAvailable: true,
|
|
43
|
+
limitSize: 100000,
|
|
44
|
+
limitCounter: 1000
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
auth:{
|
|
48
|
+
delay_auth_fail: 1000,
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
memberOnly: false
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
Binary file
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Document</title>
|
|
8
|
+
<style>
|
|
9
|
+
#messageView{
|
|
10
|
+
border: 1px solid red;
|
|
11
|
+
padding: 2em;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h2>Simple pub sub example.</h2>
|
|
17
|
+
<p>you should start server first.</p>
|
|
18
|
+
<p>this index.html load two types of modules. </p>
|
|
19
|
+
<h5>1. IIFE: iosignal.min.js</h5>
|
|
20
|
+
<p>use global name: IO </p>
|
|
21
|
+
<p>IO has props: Boho, MBP, Buffer,, </p>
|
|
22
|
+
<h5>2. ESM: iosignal.esm.js</h5>
|
|
23
|
+
<p> check the console.</p>
|
|
24
|
+
<h2>message log</h2>
|
|
25
|
+
<div id="messageView">...</div>
|
|
26
|
+
<script src="../dist/iosignal.min.js"></script>
|
|
27
|
+
<script>
|
|
28
|
+
console.log('IIFE:')
|
|
29
|
+
console.log('IO', IO)
|
|
30
|
+
console.log('MBP', IO.MBP )
|
|
31
|
+
console.log('Buffer', IO.Buffer)
|
|
32
|
+
console.log('Boho', IO.Boho )
|
|
33
|
+
console.log('sha256.hash("hi")', IO.Boho.sha256.hash('hi'))
|
|
34
|
+
|
|
35
|
+
var ESM_IO ;
|
|
36
|
+
var io1 = new IO('ws://localhost:7777')
|
|
37
|
+
var io2 = new IO('ws://localhost:7777')
|
|
38
|
+
var io3 = new IO('ws://localhost:7777')
|
|
39
|
+
|
|
40
|
+
io1.on('error', errorHandler )
|
|
41
|
+
io2.on('error', errorHandler )
|
|
42
|
+
io3.on('error', errorHandler )
|
|
43
|
+
|
|
44
|
+
let channelName = 'io'
|
|
45
|
+
// classic style subsribing
|
|
46
|
+
io1.on('ready',e=>{
|
|
47
|
+
io1.subscribe(channelName)
|
|
48
|
+
io1.on(channelName, (...args)=>{
|
|
49
|
+
// console.log('io1 received', args )
|
|
50
|
+
let msg = '[io1] ' + JSON.stringify( args )
|
|
51
|
+
addMessage(msg)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// modern style subscribing
|
|
56
|
+
io2.listen(channelName, (...args)=>{
|
|
57
|
+
// console.log('io2 receive', args )
|
|
58
|
+
let msg = '[io2] ' + JSON.stringify( args )
|
|
59
|
+
addMessage(msg)
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
setInterval(e=>{
|
|
63
|
+
io3.signal(channelName, 'single string') // single string payload
|
|
64
|
+
io3.signal(channelName, Date.now(), 'a', 2 , {key: 3} ) //multiple payload
|
|
65
|
+
io3.signal(channelName ) // pure signal without payload.
|
|
66
|
+
},3000)
|
|
67
|
+
|
|
68
|
+
function addMessage(msg){
|
|
69
|
+
|
|
70
|
+
let p = document.createElement('p')
|
|
71
|
+
p.textContent = msg
|
|
72
|
+
let v = document.querySelector('#messageView')
|
|
73
|
+
if(v.childElementCount > 20) v.innerHTML = ""
|
|
74
|
+
v.prepend( p )
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function errorHandler(e){
|
|
78
|
+
console.log(e.target)
|
|
79
|
+
addMessage('ws.error')
|
|
80
|
+
}
|
|
81
|
+
</script>
|
|
82
|
+
<script type="module">
|
|
83
|
+
import { IO, Boho, MBP, Buffer, sha256 } from "../dist/iosignal.esm.js"
|
|
84
|
+
ESM_IO = IO
|
|
85
|
+
console.log('ESM:')
|
|
86
|
+
console.log('IO', IO)
|
|
87
|
+
console.log('Boho', Boho )
|
|
88
|
+
console.log('MBP', MBP )
|
|
89
|
+
console.log('Buffer', Buffer)
|
|
90
|
+
console.log('sha256.hash("hi")', sha256.hash('hi'))
|
|
91
|
+
</script>
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
const { IO } = require('iosignal')
|
|
3
|
+
|
|
4
|
+
const io = new IO('wss://io.remocon.kr/ws')
|
|
5
|
+
|
|
6
|
+
io.on('ready', ()=>{
|
|
7
|
+
console.log('ready cid:', io.cid)
|
|
8
|
+
io.signal('#screen','playToggle')
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
io.listen('#notify', (...args)=>{
|
|
12
|
+
console.log( args )
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
io.on('error',err=>{
|
|
16
|
+
console.log('err', err)
|
|
17
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
import { IO } from "iosignal"
|
|
3
|
+
|
|
4
|
+
const io = new IO('wss://io.remocon.kr/ws')
|
|
5
|
+
|
|
6
|
+
io.on('ready', ()=>{
|
|
7
|
+
console.log('ready cid:', io.cid)
|
|
8
|
+
io.signal('#screen','playToggle')
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
io.listen('#notify', (...args)=>{
|
|
12
|
+
console.log( args )
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
io.on('error',err=>{
|
|
16
|
+
console.log('err', err)
|
|
17
|
+
})
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
let { Server, serverOption } = require('iosignal')
|
|
2
|
+
|
|
3
|
+
serverOption.showMetric = 2;
|
|
4
|
+
// serverOption.port = 7777 // default. websocket port 7777 will be open.
|
|
5
|
+
serverOption.congPort = 8888 // additional tcp cong port open. for Arduino like devices.
|
|
6
|
+
const server = new Server( serverOption )
|
|
7
|
+
console.log( 'serverOption:', serverOption )
|
|
8
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Server, serverOption } from '../index.js'
|
|
2
|
+
|
|
3
|
+
// serverOption.showMetric = 2;
|
|
4
|
+
// serverOption.showMessage = 'message';
|
|
5
|
+
// serverOption.port = '6666'
|
|
6
|
+
// serverOption.congPort = '6667'
|
|
7
|
+
|
|
8
|
+
const server = new Server( serverOption )
|
|
9
|
+
console.log( 'serverOption:', serverOption )
|
|
10
|
+
|
|
11
|
+
// text message handler (No binary message)
|
|
12
|
+
// print text message
|
|
13
|
+
// then reply.
|
|
14
|
+
server.on('text_message', (msg, remote)=>{
|
|
15
|
+
console.log('text_message from(cid): ', remote.cid, msg.toString() )
|
|
16
|
+
let result = { msg: msg, yourcid: remote.cid , date: new Date().toUTCString() }
|
|
17
|
+
let res = JSON.stringify( result )
|
|
18
|
+
remote.send( res )
|
|
19
|
+
})
|