@mixd-id/web-scaffold 0.1.230406236 → 0.1.230406238
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/package.json +10 -4
- package/src/utils/wss.js +238 -0
- package/src/utils/wss.mjs +289 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mixd-id/web-scaffold",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.230406238",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite serve",
|
|
7
7
|
"build": "vite build",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"exports": {
|
|
12
12
|
".": "./src/index.js",
|
|
13
13
|
"./themes/default": "./src/themes/default/index.js",
|
|
14
|
-
"./components
|
|
15
|
-
"./components/Textbox.vue": "./src/components/Textbox.vue",
|
|
14
|
+
"./components/*": "./src/components/*",
|
|
16
15
|
"./mixin/component": "./src/mixin/component.js",
|
|
17
16
|
"./mixin/edit-mode": "./src/mixin/edit-mode.js",
|
|
18
17
|
"./middleware/http/trim-string": "./src/middleware/http/trim-string.js",
|
|
@@ -20,6 +19,10 @@
|
|
|
20
19
|
"require": "./src/utils/helpers.js",
|
|
21
20
|
"import": "./src/utils/helpers.mjs"
|
|
22
21
|
},
|
|
22
|
+
"./wss": {
|
|
23
|
+
"require": "./src/utils/wss.js",
|
|
24
|
+
"import": "./src/utils/wss.mjs"
|
|
25
|
+
},
|
|
23
26
|
"./importer": "./src/utils/importer.js",
|
|
24
27
|
"./listpage1": "./src/utils/listpage1.js",
|
|
25
28
|
"./listview": "./src/utils/listview.js",
|
|
@@ -36,10 +39,12 @@
|
|
|
36
39
|
"compression": "^1.7.4",
|
|
37
40
|
"cookie-parser": "^1.4.6",
|
|
38
41
|
"cors": "^2.8.5",
|
|
42
|
+
"crypto-js": "^4.2.0",
|
|
39
43
|
"daisyui": "^2.19.0",
|
|
40
44
|
"dayjs": "^1.11.2",
|
|
41
45
|
"exceljs": "^4.3.0",
|
|
42
46
|
"express": "^4.18.1",
|
|
47
|
+
"eventemitter2": "^6.4.7",
|
|
43
48
|
"file-type": "^18.2.1",
|
|
44
49
|
"glob": "^8.0.3",
|
|
45
50
|
"lodash": "^4.17.21",
|
|
@@ -51,7 +56,8 @@
|
|
|
51
56
|
"tailwindcss": "^3.2.4",
|
|
52
57
|
"vue": "^3.2.25",
|
|
53
58
|
"vue-chartjs": "^5.2.0",
|
|
54
|
-
"vue-router": "^4.0.14"
|
|
59
|
+
"vue-router": "^4.0.14",
|
|
60
|
+
"ws": "^8.16.0"
|
|
55
61
|
},
|
|
56
62
|
"devDependencies": {
|
|
57
63
|
"@vitejs/plugin-vue": "^2.2.0",
|
package/src/utils/wss.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
const WebSocket = require('ws');
|
|
2
|
+
const CryptoJS = require("crypto-js");
|
|
3
|
+
const crypto = require("crypto-js");
|
|
4
|
+
const EventEmitter2 = require("eventemitter2");
|
|
5
|
+
|
|
6
|
+
const convertDataUrlObj = async(obj) => {
|
|
7
|
+
|
|
8
|
+
const processObjectProperties = async (inputObj) => {
|
|
9
|
+
|
|
10
|
+
let outputObj
|
|
11
|
+
|
|
12
|
+
if(Array.isArray(inputObj)){
|
|
13
|
+
outputObj = []
|
|
14
|
+
|
|
15
|
+
for(let i = 0; i < inputObj.length; i++){
|
|
16
|
+
const value = inputObj[i];
|
|
17
|
+
|
|
18
|
+
if (Buffer.isBuffer(value)) {
|
|
19
|
+
outputObj[i] = value.toString('base64')
|
|
20
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
21
|
+
outputObj[i] = await processObjectProperties(value);
|
|
22
|
+
} else {
|
|
23
|
+
outputObj[i] = value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
else if(typeof inputObj === 'object' && inputObj !== null){
|
|
28
|
+
outputObj = {};
|
|
29
|
+
for (const key in inputObj) {
|
|
30
|
+
if (inputObj.hasOwnProperty(key)) {
|
|
31
|
+
const value = inputObj[key];
|
|
32
|
+
|
|
33
|
+
if (Buffer.isBuffer(value)) {
|
|
34
|
+
outputObj[key] = value.toString('base64')
|
|
35
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
36
|
+
outputObj[key] = await processObjectProperties(value);
|
|
37
|
+
} else {
|
|
38
|
+
outputObj[key] = value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return outputObj;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return processObjectProperties(obj);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const revertDataUrlObj = (obj) => {
|
|
51
|
+
|
|
52
|
+
// Recursive function to process each property of the object
|
|
53
|
+
const processObjectProperties = async (inputObj) => {
|
|
54
|
+
let outputObj;
|
|
55
|
+
|
|
56
|
+
if(Array.isArray(inputObj)){
|
|
57
|
+
outputObj = []
|
|
58
|
+
for (let i = 0; i < inputObj.length; i++) {
|
|
59
|
+
let value = inputObj[i];
|
|
60
|
+
|
|
61
|
+
if (typeof value === 'string' && value.startsWith('data:')) {
|
|
62
|
+
if(value.indexOf(',') >= 0){
|
|
63
|
+
value = value.substring(value.indexOf(',') + 1)
|
|
64
|
+
}
|
|
65
|
+
outputObj[i] = Buffer.from(value, 'base64');
|
|
66
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
67
|
+
outputObj[i] = await processObjectProperties(value);
|
|
68
|
+
} else {
|
|
69
|
+
outputObj[i] = value;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else{
|
|
74
|
+
outputObj = {}
|
|
75
|
+
|
|
76
|
+
for (const key in inputObj) {
|
|
77
|
+
if (inputObj.hasOwnProperty(key)) {
|
|
78
|
+
let value = inputObj[key];
|
|
79
|
+
|
|
80
|
+
if (typeof value === 'string' && value.startsWith('data:')) {
|
|
81
|
+
if(value.indexOf(',') >= 0){
|
|
82
|
+
value = value.substring(value.indexOf(',') + 1)
|
|
83
|
+
}
|
|
84
|
+
outputObj[key] = Buffer.from(value, 'base64');
|
|
85
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
86
|
+
outputObj[key] = await processObjectProperties(value);
|
|
87
|
+
} else {
|
|
88
|
+
outputObj[key] = value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
return outputObj;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// Start processing the top-level object
|
|
99
|
+
return processObjectProperties(obj);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class WSS extends EventEmitter2{
|
|
104
|
+
|
|
105
|
+
_instance
|
|
106
|
+
_opt
|
|
107
|
+
|
|
108
|
+
emits = [ ]
|
|
109
|
+
|
|
110
|
+
_authFn = []
|
|
111
|
+
_reqFn = []
|
|
112
|
+
|
|
113
|
+
async fromBinaryData(binaryData){
|
|
114
|
+
const secretKey = this._opt.key;
|
|
115
|
+
const encryptedString = Buffer.from(binaryData).toString('utf-8');
|
|
116
|
+
const decryptedData = CryptoJS.AES.decrypt(encryptedString, secretKey).toString(CryptoJS.enc.Utf8);
|
|
117
|
+
const receivedObject = JSON.parse(decryptedData);
|
|
118
|
+
return await revertDataUrlObj(receivedObject);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
async toBinaryData(obj){
|
|
122
|
+
const secretKey = this._opt.key;
|
|
123
|
+
const dataUrlObj = await convertDataUrlObj(obj)
|
|
124
|
+
const encryptedData = crypto.AES.encrypt(JSON.stringify(dataUrlObj), secretKey).toString();
|
|
125
|
+
return new TextEncoder().encode(encryptedData);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
constructor(opt) {
|
|
129
|
+
super()
|
|
130
|
+
|
|
131
|
+
this._opt = opt
|
|
132
|
+
this._instance = new WebSocket.Server(opt);
|
|
133
|
+
|
|
134
|
+
this._instance.on('connection', (socket, req) => {
|
|
135
|
+
|
|
136
|
+
socket.leave = (channel) => {
|
|
137
|
+
if((socket.channels ?? {})[channel]){
|
|
138
|
+
delete socket.channels[channel]
|
|
139
|
+
//console.log('leave', channel)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
socket.join = (channel) => {
|
|
144
|
+
if(!socket.channels){
|
|
145
|
+
socket.channels = {}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
socket.channels[channel] = 1
|
|
149
|
+
//console.log('join', channel)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
socket.to = (channel) => {
|
|
153
|
+
return {
|
|
154
|
+
emit: (model, event, items) => {
|
|
155
|
+
this.broadcast(channel, { model, event, items }).then()
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
socket.on('message', async (binaryData) => {
|
|
161
|
+
|
|
162
|
+
const { _requestId, path, params } = await this.fromBinaryData(binaryData);
|
|
163
|
+
|
|
164
|
+
let status = 200
|
|
165
|
+
let data
|
|
166
|
+
switch(path){
|
|
167
|
+
|
|
168
|
+
case '_auth':
|
|
169
|
+
try{
|
|
170
|
+
for(let fn of this._authFn){
|
|
171
|
+
await fn(params, socket)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch(e){
|
|
175
|
+
socket.close(1002, e.message);
|
|
176
|
+
}
|
|
177
|
+
break
|
|
178
|
+
|
|
179
|
+
case 'ping':
|
|
180
|
+
data = { type:'pong' }
|
|
181
|
+
break
|
|
182
|
+
|
|
183
|
+
default:
|
|
184
|
+
try{
|
|
185
|
+
const arr = (await Promise.all(this._reqFn.map(fn => fn({ path, params }, socket))))
|
|
186
|
+
.filter(_ => _)
|
|
187
|
+
|
|
188
|
+
data = arr.length > 0 ? JSON.parse(JSON.stringify(arr.pop())) : data
|
|
189
|
+
}
|
|
190
|
+
catch(e){
|
|
191
|
+
status = 500
|
|
192
|
+
data = {
|
|
193
|
+
name: e.name,
|
|
194
|
+
message: e.message,
|
|
195
|
+
errors: e.errors,
|
|
196
|
+
stack: process.env.APP_DEBUG === 'true' ?
|
|
197
|
+
e.stack : undefined
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
break
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
socket.send(await this.toBinaryData({
|
|
204
|
+
_requestId,
|
|
205
|
+
status,
|
|
206
|
+
data
|
|
207
|
+
}))
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
socket.on('close', (e) => {
|
|
211
|
+
this.emit('close', e, socket)
|
|
212
|
+
});
|
|
213
|
+
})
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
auth(fn){
|
|
217
|
+
this._authFn.push(fn)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
req(fn){
|
|
221
|
+
this._reqFn.push(fn)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async broadcast(channel, { model, event, items }){
|
|
225
|
+
//console.log('broadcast', channel, JSON.stringify({ model, event, items }).substring(0, 70))
|
|
226
|
+
|
|
227
|
+
for(let socket of this._instance.clients){
|
|
228
|
+
if(socket.readyState === WebSocket.OPEN && (socket.channels ?? {})[channel]){
|
|
229
|
+
socket.send(await this.toBinaryData({ data:{ model, event, items } }))
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
module.exports = {
|
|
237
|
+
WSS
|
|
238
|
+
}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import CryptoJS from "crypto-js";
|
|
2
|
+
import EventEmitter2 from "eventemitter2";
|
|
3
|
+
|
|
4
|
+
class WSS extends EventEmitter2{
|
|
5
|
+
|
|
6
|
+
_instance
|
|
7
|
+
_opt
|
|
8
|
+
_counter = 0
|
|
9
|
+
_callbacks = {}
|
|
10
|
+
_pendingSend = []
|
|
11
|
+
_lastBlurAt
|
|
12
|
+
|
|
13
|
+
static async convertDataUrlObj(obj){
|
|
14
|
+
|
|
15
|
+
const fileToDataURL = (file) => {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const reader = new FileReader();
|
|
18
|
+
reader.onload = (event) => resolve(event.target.result);
|
|
19
|
+
reader.onerror = (error) => reject(error);
|
|
20
|
+
reader.readAsDataURL(file);
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const processObjectProperties = async (inputObj) => {
|
|
25
|
+
let outputObj;
|
|
26
|
+
|
|
27
|
+
if(Array.isArray(inputObj)){
|
|
28
|
+
outputObj = []
|
|
29
|
+
for(let i = 0; i < inputObj.length; i++){
|
|
30
|
+
const value = inputObj[i];
|
|
31
|
+
|
|
32
|
+
if (value instanceof File) {
|
|
33
|
+
outputObj[i] = await fileToDataURL(value);
|
|
34
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
35
|
+
outputObj[i] = await processObjectProperties(value);
|
|
36
|
+
} else {
|
|
37
|
+
outputObj[i] = value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
else{
|
|
42
|
+
outputObj = {}
|
|
43
|
+
|
|
44
|
+
for (const key in inputObj) {
|
|
45
|
+
if (inputObj.hasOwnProperty(key)) {
|
|
46
|
+
const value = inputObj[key];
|
|
47
|
+
|
|
48
|
+
if (value instanceof File) {
|
|
49
|
+
outputObj[key] = await fileToDataURL(value);
|
|
50
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
51
|
+
outputObj[key] = await processObjectProperties(value);
|
|
52
|
+
} else {
|
|
53
|
+
outputObj[key] = value;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
return outputObj;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
return processObjectProperties(obj);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async revertDataUrlObj(obj){
|
|
67
|
+
|
|
68
|
+
const processObjectProperties = async (inputObj) => {
|
|
69
|
+
let outputObj;
|
|
70
|
+
|
|
71
|
+
if(Array.isArray(inputObj)){
|
|
72
|
+
outputObj = []
|
|
73
|
+
for (let i = 0; i < inputObj.length; i++) {
|
|
74
|
+
let value = inputObj[i];
|
|
75
|
+
|
|
76
|
+
if (typeof value === 'object' && value !== null) {
|
|
77
|
+
outputObj[i] = await processObjectProperties(value);
|
|
78
|
+
} else {
|
|
79
|
+
outputObj[i] = value;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if(typeof inputObj === 'object' && inputObj !== null){
|
|
84
|
+
outputObj = {}
|
|
85
|
+
for (const key in inputObj) {
|
|
86
|
+
if (inputObj.hasOwnProperty(key)) {
|
|
87
|
+
let value = inputObj[key];
|
|
88
|
+
|
|
89
|
+
if (typeof value === 'object' && value !== null) {
|
|
90
|
+
outputObj[key] = await processObjectProperties(value);
|
|
91
|
+
} else {
|
|
92
|
+
outputObj[key] = value;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return outputObj;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return processObjectProperties(obj);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
constructor(opt) {
|
|
105
|
+
super();
|
|
106
|
+
|
|
107
|
+
this._opt = Object.assign({
|
|
108
|
+
auth: {},
|
|
109
|
+
debug: false,
|
|
110
|
+
key: '',
|
|
111
|
+
onConnect: null,
|
|
112
|
+
onConnectError: null,
|
|
113
|
+
onDisconnect: null,
|
|
114
|
+
timeout: 30000,
|
|
115
|
+
url: '',
|
|
116
|
+
}, opt ?? {})
|
|
117
|
+
|
|
118
|
+
if(typeof window !== 'undefined'){
|
|
119
|
+
window.addEventListener('online', this._onOnlineChanged)
|
|
120
|
+
window.addEventListener('offline', this._onOnlineChanged)
|
|
121
|
+
window.addEventListener('blur', this._onBlur)
|
|
122
|
+
window.addEventListener('focus', this._onFocus)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.connect().then()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
_onBlur = () => {
|
|
129
|
+
this._lastBlurAt = new Date().getTime()
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
_onFocus = () => {
|
|
133
|
+
this.emit('focus')
|
|
134
|
+
|
|
135
|
+
if(this._lastBlurAt){
|
|
136
|
+
this.send('ping', {}, { timeout:1000 })
|
|
137
|
+
.catch(_ => {
|
|
138
|
+
this.reconnect().then()
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
_onOnlineChanged = (e) => {
|
|
144
|
+
if(!navigator.onLine){
|
|
145
|
+
this.emit('disconnect', e)
|
|
146
|
+
}
|
|
147
|
+
else{
|
|
148
|
+
this.emit('connect')
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async fromBinaryData(binaryData){
|
|
153
|
+
const secretKey = this._opt.key;
|
|
154
|
+
const encryptedString = new TextDecoder().decode(binaryData)
|
|
155
|
+
const decryptedData = CryptoJS.AES.decrypt(encryptedString, secretKey).toString(CryptoJS.enc.Utf8);
|
|
156
|
+
const receivedObject = JSON.parse(decryptedData);
|
|
157
|
+
return await WSS.revertDataUrlObj(receivedObject);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async toBinaryData(obj){
|
|
161
|
+
const secretKey = this._opt.key;
|
|
162
|
+
const encryptedData = CryptoJS.AES.encrypt(JSON.stringify(obj), secretKey).toString();
|
|
163
|
+
return new TextEncoder().encode(encryptedData)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async connect(reconnect = false){
|
|
167
|
+
|
|
168
|
+
this._instance = new WebSocket(this._opt.url)
|
|
169
|
+
|
|
170
|
+
this._instance.binaryType = 'arraybuffer';
|
|
171
|
+
|
|
172
|
+
this._instance.onopen = () => {
|
|
173
|
+
this.send('_auth', this._opt.auth)
|
|
174
|
+
.then(() => {
|
|
175
|
+
reconnect ? this.emit('reconnect') : this.emit('connect')
|
|
176
|
+
|
|
177
|
+
for(let sendParams of this._pendingSend){
|
|
178
|
+
this.sendSync(sendParams.path, sendParams.params, sendParams.cb, sendParams.err)
|
|
179
|
+
}
|
|
180
|
+
this._pendingSend = []
|
|
181
|
+
})
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
this._instance.onmessage = async (event) => {
|
|
185
|
+
const obj = await this.fromBinaryData(event.data);
|
|
186
|
+
|
|
187
|
+
const { _requestId, status, data } = obj
|
|
188
|
+
|
|
189
|
+
if(_requestId){
|
|
190
|
+
if(this._callbacks[_requestId]){
|
|
191
|
+
const { cb, err, path, params, t1 } = this._callbacks[_requestId]
|
|
192
|
+
status === 200 ? cb(data) : err(data)
|
|
193
|
+
delete this._callbacks[_requestId]
|
|
194
|
+
|
|
195
|
+
if(this._opt.debug){
|
|
196
|
+
console.log(new Date().getTime() - t1, path, params, data)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else{
|
|
201
|
+
const { model, event, items } = data
|
|
202
|
+
this.emit(model, event, items)
|
|
203
|
+
|
|
204
|
+
if(this._opt.debug){
|
|
205
|
+
console.log('SIGNAL', model, event, items)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
this._instance.onerror = (e) => {
|
|
212
|
+
this.emit('error', e)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
this._instance.onclose = (e) => {
|
|
216
|
+
|
|
217
|
+
switch(e.code){
|
|
218
|
+
|
|
219
|
+
case 1002:
|
|
220
|
+
this.emit('connect_error', e)
|
|
221
|
+
break
|
|
222
|
+
|
|
223
|
+
default:
|
|
224
|
+
this.emit('disconnect')
|
|
225
|
+
break
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async reconnect(){
|
|
231
|
+
if(this._instance){
|
|
232
|
+
this._instance.close()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
await this.connect(true)
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
sendSync(path, params, cb, err, override){
|
|
239
|
+
if(this._instance.readyState !== 1){
|
|
240
|
+
this._pendingSend.push({ path, params, cb, err })
|
|
241
|
+
return
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if(!navigator.onLine){
|
|
245
|
+
err({ message: 'Unable to send, network disconnected' })
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const _requestId = ++this._counter
|
|
250
|
+
|
|
251
|
+
WSS.convertDataUrlObj({
|
|
252
|
+
_requestId,
|
|
253
|
+
path,
|
|
254
|
+
params
|
|
255
|
+
})
|
|
256
|
+
.then(async(dataUrlObj) => {
|
|
257
|
+
const binaryData = await this.toBinaryData(dataUrlObj)
|
|
258
|
+
this._instance.send(binaryData)
|
|
259
|
+
|
|
260
|
+
this._callbacks[_requestId] = {
|
|
261
|
+
cb,
|
|
262
|
+
err,
|
|
263
|
+
path,
|
|
264
|
+
params,
|
|
265
|
+
t1: new Date().getTime()
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
setTimeout(() => {
|
|
269
|
+
if(this._callbacks[_requestId]){
|
|
270
|
+
err({ message: 'Timeout' })
|
|
271
|
+
delete this._callbacks[_requestId]
|
|
272
|
+
|
|
273
|
+
this.reconnect()
|
|
274
|
+
}
|
|
275
|
+
}, (override ?? {}).timeout ?? this._opt.timeout)
|
|
276
|
+
})
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
send(path, params, override){
|
|
280
|
+
return new Promise((resolve, reject) => {
|
|
281
|
+
this.sendSync(path, params, resolve, reject, override)
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export {
|
|
288
|
+
WSS
|
|
289
|
+
}
|