asai-nodejs-host 0.1.0 → 0.1.1
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 +9 -1
- package/AsaiHost.js +0 -532
- package/AsaiHost.ts +0 -522
- package/asai-nodejs-host/index.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "asai-nodejs-host",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "asai for you",
|
|
5
5
|
"author": "Asai",
|
|
6
6
|
"license": "ISC",
|
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "https://gitee.com/guoyansai/asaiplug/asai-nodejs-host"
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
"index.js",
|
|
14
|
+
"lib/",
|
|
15
|
+
"!node_modules",
|
|
16
|
+
"!asai-nodejs-host",
|
|
17
|
+
"!AsaiHost.js",
|
|
18
|
+
"!AsaiHost.ts"
|
|
19
|
+
],
|
|
12
20
|
"scripts": {
|
|
13
21
|
"tsc": "tsc AsaiHost.ts",
|
|
14
22
|
"ncc": "npm run tsc && ncc build ./AsaiHost.js -m -o ./asai-nodejs-host/",
|
package/AsaiHost.js
DELETED
|
@@ -1,532 +0,0 @@
|
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
|
2
|
-
__assign = Object.assign || function(t) {
|
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
-
s = arguments[i];
|
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
-
t[p] = s[p];
|
|
7
|
-
}
|
|
8
|
-
return t;
|
|
9
|
-
};
|
|
10
|
-
return __assign.apply(this, arguments);
|
|
11
|
-
};
|
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
23
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
25
|
-
function step(op) {
|
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
30
|
-
switch (op[0]) {
|
|
31
|
-
case 0: case 1: t = op; break;
|
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
35
|
-
default:
|
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
40
|
-
if (t[2]) _.ops.pop();
|
|
41
|
-
_.trys.pop(); continue;
|
|
42
|
-
}
|
|
43
|
-
op = body.call(thisArg, _);
|
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
49
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
50
|
-
if (ar || !(i in from)) {
|
|
51
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
52
|
-
ar[i] = from[i];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
56
|
-
};
|
|
57
|
-
module.exports = function ($asai, opt) {
|
|
58
|
-
var _a, _b, _c;
|
|
59
|
-
var sysWork = opt.sysWork, apiWork = opt.apiWork, wsWork = opt.wsWork;
|
|
60
|
-
var fs = require("fs");
|
|
61
|
-
var path = require("path");
|
|
62
|
-
var url = require("url");
|
|
63
|
-
// 读取配置文件
|
|
64
|
-
if (!((_a = $asai.hostconfig) === null || _a === void 0 ? void 0 : _a.ip)) {
|
|
65
|
-
$asai.hostconfig.ip = getIp();
|
|
66
|
-
}
|
|
67
|
-
// 通过环境变量控制日志输出
|
|
68
|
-
// if (process.env.NODE_ENV === 'production') {
|
|
69
|
-
// console.log = () => {}; // 关闭调试日志
|
|
70
|
-
// }
|
|
71
|
-
console.log("\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B\u203B");
|
|
72
|
-
// 获取http或https的服务
|
|
73
|
-
// const http: any = require('http2');
|
|
74
|
-
var http = require("http");
|
|
75
|
-
var https = require("https");
|
|
76
|
-
// 获取当前时间
|
|
77
|
-
function getNowTime() {
|
|
78
|
-
var datanow = new Date();
|
|
79
|
-
return (datanow.getMonth() +
|
|
80
|
-
1 +
|
|
81
|
-
"-" +
|
|
82
|
-
datanow.getDate() +
|
|
83
|
-
" " +
|
|
84
|
-
datanow.getHours() +
|
|
85
|
-
":" +
|
|
86
|
-
datanow.getMinutes() +
|
|
87
|
-
":" +
|
|
88
|
-
datanow.getSeconds() +
|
|
89
|
-
"." +
|
|
90
|
-
datanow.getMilliseconds());
|
|
91
|
-
}
|
|
92
|
-
// 获取本机IP地址
|
|
93
|
-
function getIp() {
|
|
94
|
-
var ifaces = require("os").networkInterfaces();
|
|
95
|
-
for (var el in ifaces) {
|
|
96
|
-
var iface = ifaces[el];
|
|
97
|
-
if (iface && iface.length) {
|
|
98
|
-
for (var i = 0; i < iface.length; i++) {
|
|
99
|
-
var elc = iface[i];
|
|
100
|
-
if (elc.family === "IPv4" &&
|
|
101
|
-
elc.address !== "127.0.0.1" &&
|
|
102
|
-
!elc.internal) {
|
|
103
|
-
return elc.address;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return "";
|
|
109
|
-
}
|
|
110
|
-
function getHTTPServer() {
|
|
111
|
-
try {
|
|
112
|
-
if ($asai.hostconfig.httptype.includes("https")) {
|
|
113
|
-
https.AsCreateServer = function (callback) {
|
|
114
|
-
return https.createServer($asai.hostconfig.httpscert, callback);
|
|
115
|
-
};
|
|
116
|
-
return https;
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
http.AsCreateServer = http.createServer;
|
|
120
|
-
return http;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
catch (err) {
|
|
124
|
-
console.log(666.907, err);
|
|
125
|
-
http.AsCreateServer = http.createServer;
|
|
126
|
-
return http;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
function getWsUserinfo(req) {
|
|
130
|
-
var _a;
|
|
131
|
-
try {
|
|
132
|
-
var headers = Object.fromEntries(Array.from({ length: req.rawHeaders.length / 2 }, function (_, i) { return [
|
|
133
|
-
req.rawHeaders[i * 2].toLowerCase(),
|
|
134
|
-
req.rawHeaders[i * 2 + 1],
|
|
135
|
-
]; }));
|
|
136
|
-
var userinfo = (_a = headers["sec-websocket-protocol"]) === null || _a === void 0 ? void 0 : _a.split("##");
|
|
137
|
-
return deUserInfo(userinfo);
|
|
138
|
-
}
|
|
139
|
-
catch (err) { }
|
|
140
|
-
return null;
|
|
141
|
-
}
|
|
142
|
-
// Ws请求头校验
|
|
143
|
-
function checkWsHeader(req) {
|
|
144
|
-
req.Userinfo = getWsUserinfo(req);
|
|
145
|
-
console.log(666.2001, "WS", req.Userinfo[0]);
|
|
146
|
-
return true;
|
|
147
|
-
}
|
|
148
|
-
function getHttpUserinfo(req) {
|
|
149
|
-
var _a;
|
|
150
|
-
try {
|
|
151
|
-
var headers = Object.fromEntries(Array.from({ length: req.rawHeaders.length / 2 }, function (_, i) { return [
|
|
152
|
-
req.rawHeaders[i * 2].toLowerCase(),
|
|
153
|
-
req.rawHeaders[i * 2 + 1],
|
|
154
|
-
]; }));
|
|
155
|
-
var userinfo = (_a = headers["userinfo"]) === null || _a === void 0 ? void 0 : _a.split("##");
|
|
156
|
-
return deUserInfo(userinfo);
|
|
157
|
-
}
|
|
158
|
-
catch (err) { }
|
|
159
|
-
return null;
|
|
160
|
-
}
|
|
161
|
-
// tcp请求头校验
|
|
162
|
-
function checkHttpHeader(req) {
|
|
163
|
-
req.Userinfo = getHttpUserinfo(req);
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
function deUserInfo(userinfo) {
|
|
167
|
-
if (userinfo[2]) {
|
|
168
|
-
userinfo[2] = $asai.$lib.AsCode.asdecode(userinfo[2], $asai.hostconfig.asaisn);
|
|
169
|
-
userinfo[0] = $asai.$lib.AsCode.asdecode(userinfo[0], userinfo[2]);
|
|
170
|
-
userinfo[1] = $asai.$lib.AsCode.asdecode(userinfo[1], userinfo[2]);
|
|
171
|
-
}
|
|
172
|
-
return userinfo;
|
|
173
|
-
}
|
|
174
|
-
// 代理服务器
|
|
175
|
-
if ((_b = $asai.hostconfig) === null || _b === void 0 ? void 0 : _b.proxyhosts) {
|
|
176
|
-
// 循环启动配置中的服务
|
|
177
|
-
Object.keys($asai.hostconfig.proxyhosts).forEach(function (el) {
|
|
178
|
-
startProxyServer(el);
|
|
179
|
-
});
|
|
180
|
-
// 启动代理服务器
|
|
181
|
-
function startProxyServer(proxyhost) {
|
|
182
|
-
var proxycfg = $asai.hostconfig.proxyhosts[proxyhost];
|
|
183
|
-
if (!proxycfg.url && proxycfg.port) {
|
|
184
|
-
proxycfg.url =
|
|
185
|
-
$asai.hostconfig.httptype + $asai.hostconfig.ip + ":" + proxycfg.port;
|
|
186
|
-
}
|
|
187
|
-
if (proxycfg.url) {
|
|
188
|
-
var http_1 = getHTTPServer();
|
|
189
|
-
var proxyServer = http_1.AsCreateServer(function (req, res) {
|
|
190
|
-
// 启用Keep-Alive复用连接
|
|
191
|
-
var agent = new http_1.Agent({ keepAlive: true });
|
|
192
|
-
var forwardRequest = http_1.request(__assign({ agent: agent, method: req.method }, url.parse(proxycfg.url + req.url)), function (forwardRes) {
|
|
193
|
-
// 设置响应头(可以选择性地转发原始响应头)
|
|
194
|
-
Object.keys(forwardRes.headers).forEach(function (key) {
|
|
195
|
-
res.setHeader(key, forwardRes.headers[key]);
|
|
196
|
-
});
|
|
197
|
-
res.statusCode = forwardRes.statusCode;
|
|
198
|
-
console.log(666.001, getHttpUserinfo(req));
|
|
199
|
-
res.setHeader("Userinfo", getHttpUserinfo(req));
|
|
200
|
-
// 转发响应数据
|
|
201
|
-
req.pipe(forwardRequest); // 自动处理背压
|
|
202
|
-
forwardRes.pipe(res);
|
|
203
|
-
// forwardRes.pipe(res, { end: true }); // 手动数据传递
|
|
204
|
-
});
|
|
205
|
-
// 处理转发请求的错误
|
|
206
|
-
forwardRequest.on("error", function (err) {
|
|
207
|
-
console.error("Error during forward request:", err);
|
|
208
|
-
res.writeHead(502); // Bad Gateway
|
|
209
|
-
res.end("Bad Gateway");
|
|
210
|
-
});
|
|
211
|
-
// 转发请求数据
|
|
212
|
-
req.pipe(forwardRequest, { end: true });
|
|
213
|
-
// 请求超时
|
|
214
|
-
forwardRequest.setTimeout(50000, function () {
|
|
215
|
-
forwardRequest.destroy();
|
|
216
|
-
res.writeHead(504);
|
|
217
|
-
res.end("Gateway Timeout");
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
if (proxycfg.proxyip) {
|
|
221
|
-
proxyServer.listen(proxycfg.proxyport || $asai.hostconfig.proxyport, proxycfg.proxyip, function () {
|
|
222
|
-
console.log("[".concat(proxyhost, "] Start At ").concat(getNowTime(), "."));
|
|
223
|
-
console.log("\u001B[45;28mProxy Server ".concat($asai.hostconfig.httptype).concat(proxycfg.proxyip, ":").concat(proxycfg.proxyport || $asai.hostconfig.proxyport, "\u001B[0m"));
|
|
224
|
-
console.log("================================================");
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
proxyServer.listen(proxycfg.proxyport || $asai.hostconfig.proxyport, function () {
|
|
229
|
-
console.log("[".concat(proxyhost, "] Start At ").concat(getNowTime(), "."));
|
|
230
|
-
console.log("\u001B[45;28mProxy server ".concat($asai.hostconfig.httptype, "localhost:").concat(proxycfg.proxyport || $asai.hostconfig.proxyport, "\u001B[0m"));
|
|
231
|
-
console.log("================================================");
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
// 网页与文件服务器
|
|
238
|
-
if ((_c = $asai.hostconfig) === null || _c === void 0 ? void 0 : _c.hosts) {
|
|
239
|
-
$asai.startHTTPServer = startHTTPServer;
|
|
240
|
-
// 循环启动配置中的服务
|
|
241
|
-
Object.keys($asai.hostconfig.hosts).forEach(function (el) {
|
|
242
|
-
startHTTPServer(el);
|
|
243
|
-
});
|
|
244
|
-
// 创建WS服务
|
|
245
|
-
function createWSHost(hostdir) {
|
|
246
|
-
try {
|
|
247
|
-
if (!$asai.serversws[hostdir]) {
|
|
248
|
-
var _a = require("ws"), WebSocket_1 = _a.WebSocket, WebSocketServer = _a.WebSocketServer;
|
|
249
|
-
var wsopt = {};
|
|
250
|
-
// ws的配置项
|
|
251
|
-
$asai.serversws[hostdir] = new WebSocketServer({
|
|
252
|
-
server: $asai.servershttp[hostdir],
|
|
253
|
-
// 附加配置信息
|
|
254
|
-
perMessageDeflate: false, // 关闭压缩减少CPU开销
|
|
255
|
-
// perMessageDeflate: {
|
|
256
|
-
// zlibDeflateOptions: {
|
|
257
|
-
// // See zlib defaults.
|
|
258
|
-
// chunkSize: 1024,
|
|
259
|
-
// memLevel: 7,
|
|
260
|
-
// level: 3,
|
|
261
|
-
// },
|
|
262
|
-
// zlibInflateOptions: {
|
|
263
|
-
// chunkSize: 10 * 1024,
|
|
264
|
-
// },
|
|
265
|
-
// // Other options settable:
|
|
266
|
-
// clientNoContextTakeover: true, // Defaults to negotiated value.
|
|
267
|
-
// serverNoContextTakeover: true, // Defaults to negotiated value.
|
|
268
|
-
// serverMaxWindowBits: 10, // Defaults to negotiated value.
|
|
269
|
-
// // Below options specified as default values.
|
|
270
|
-
// concurrencyLimit: 10, // Limits zlib concurrency for perf.
|
|
271
|
-
// threshold: 1024, // Size (in bytes) below which messages
|
|
272
|
-
// // should not be compressed if context takeover is disabled.
|
|
273
|
-
// },
|
|
274
|
-
});
|
|
275
|
-
// 服务器ws服务关闭操作,清空定时器
|
|
276
|
-
function wsServerClose() {
|
|
277
|
-
if ($asai.tasksws[hostdir] &&
|
|
278
|
-
typeof $asai.tasksws[hostdir] === "object") {
|
|
279
|
-
Object.values($asai.tasksws[hostdir]).forEach(function (el) {
|
|
280
|
-
el && clearInterval(el);
|
|
281
|
-
});
|
|
282
|
-
$asai.tasksws[hostdir] = {};
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
// 服务端异常错误关闭
|
|
286
|
-
$asai.serversws[hostdir].on("error", function () {
|
|
287
|
-
wsServerClose();
|
|
288
|
-
$asai.hostconfig.log && console.log(666.303, "WS Server error!");
|
|
289
|
-
});
|
|
290
|
-
// 服务端异常关闭
|
|
291
|
-
$asai.serversws[hostdir].on("close", function () {
|
|
292
|
-
wsServerClose();
|
|
293
|
-
$asai.hostconfig.log && console.log(666.301, "WS Server close!");
|
|
294
|
-
});
|
|
295
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
296
|
-
// 初始化记录ws服务连接
|
|
297
|
-
if (!$asai.connectionsws[hostdir]) {
|
|
298
|
-
$asai.connectionsws[hostdir] = new WeakMap();
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
// 服务被连接后...
|
|
302
|
-
$asai.serversws[hostdir].on("connection", function (ws, req) {
|
|
303
|
-
if (!$asai.tasksws[hostdir]) {
|
|
304
|
-
$asai.tasksws[hostdir] = {};
|
|
305
|
-
}
|
|
306
|
-
if (!(ws === null || ws === void 0 ? void 0 : ws.tasksws)) {
|
|
307
|
-
ws.tasksws = {};
|
|
308
|
-
}
|
|
309
|
-
if (checkWsHeader(req)) {
|
|
310
|
-
$asai.hostconfig.log &&
|
|
311
|
-
console.log(666.2002, req.Userinfo, "wsClient connection!");
|
|
312
|
-
function closeWs() {
|
|
313
|
-
ws.close();
|
|
314
|
-
}
|
|
315
|
-
if ($asai.hostconfig.status.connectionsws &&
|
|
316
|
-
(!req.Userinfo[0] ||
|
|
317
|
-
!req.Userinfo[2] ||
|
|
318
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]])) {
|
|
319
|
-
// 连接用户信息不符合条件,已存在同账户的登录
|
|
320
|
-
closeWs();
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
$asai.hostconfig.log && console.log(666.2006, "ok!");
|
|
324
|
-
// 正常登录
|
|
325
|
-
var _a = req.Userinfo || [], us = _a[0], lv = _a[1], tk = _a[2];
|
|
326
|
-
ws.Userinfo = { us: us, lv: lv, tk: tk }; // 赋值给ws
|
|
327
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
328
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]] = ws;
|
|
329
|
-
}
|
|
330
|
-
// 发送消息
|
|
331
|
-
$asai.serversws[hostdir].sendws = function (msg, type, curws) {
|
|
332
|
-
if (type) {
|
|
333
|
-
// 广播消息
|
|
334
|
-
// wsopt.ulen = 0;
|
|
335
|
-
$asai.serversws[hostdir].clients.forEach(function (client) {
|
|
336
|
-
// wsopt.ulen++;
|
|
337
|
-
if ((type == 2 || client !== curws) &&
|
|
338
|
-
client.readyState == WebSocket_1.OPEN) {
|
|
339
|
-
client.send(msg);
|
|
340
|
-
}
|
|
341
|
-
console.info(666.801, client.Userinfo);
|
|
342
|
-
});
|
|
343
|
-
// $asai.hostconfig.log &&
|
|
344
|
-
// console.log(666.808, "wsClient Public!", wsopt.ulen);
|
|
345
|
-
}
|
|
346
|
-
else {
|
|
347
|
-
// api方式回复消息
|
|
348
|
-
curws.send(msg);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
//监听客户端发来的消息
|
|
352
|
-
ws.on("message", function (msg) {
|
|
353
|
-
wsWork(msg, ws, hostdir, req);
|
|
354
|
-
});
|
|
355
|
-
// 客户端关闭
|
|
356
|
-
ws.on("close", function (err) {
|
|
357
|
-
$asai.hostconfig.log &&
|
|
358
|
-
console.log(666.103, req.Userinfo[0] + " wsClient close!", err);
|
|
359
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
360
|
-
// 关闭点对点客户端的任务
|
|
361
|
-
if (ws.tasksws && typeof ws.tasksws === "object") {
|
|
362
|
-
Object.values(ws.tasksws).forEach(function (el) {
|
|
363
|
-
el && clearInterval(el);
|
|
364
|
-
});
|
|
365
|
-
ws.tasksws = null;
|
|
366
|
-
}
|
|
367
|
-
if (req.Userinfo[0] &&
|
|
368
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]]) {
|
|
369
|
-
delete $asai.connectionsws[hostdir][req.Userinfo[0]];
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
catch (err) { }
|
|
379
|
-
return $asai.serversws[hostdir];
|
|
380
|
-
}
|
|
381
|
-
// 请求的文件相对路径
|
|
382
|
-
function getFilePath(hostdir, requrl) {
|
|
383
|
-
var filePath = "" + requrl;
|
|
384
|
-
if (filePath == "/" || filePath == "") {
|
|
385
|
-
filePath = "/index.html";
|
|
386
|
-
}
|
|
387
|
-
if (hostdir == "home") {
|
|
388
|
-
filePath = "." + filePath;
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
filePath = "./" + hostdir + filePath;
|
|
392
|
-
}
|
|
393
|
-
return filePath;
|
|
394
|
-
}
|
|
395
|
-
// 读取服务器上文件
|
|
396
|
-
function fsReadFile(hostdirs, requrl) {
|
|
397
|
-
var _this = this;
|
|
398
|
-
return new Promise(function (resolve, reject) {
|
|
399
|
-
// 尝试顺序读取多个路径
|
|
400
|
-
var tryRead = function () {
|
|
401
|
-
var args_1 = [];
|
|
402
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
403
|
-
args_1[_i] = arguments[_i];
|
|
404
|
-
}
|
|
405
|
-
return __awaiter(_this, __spreadArray([], args_1, true), void 0, function (index) {
|
|
406
|
-
var filePath;
|
|
407
|
-
if (index === void 0) { index = 0; }
|
|
408
|
-
return __generator(this, function (_a) {
|
|
409
|
-
if (index >= hostdirs.length)
|
|
410
|
-
return [2 /*return*/, reject(404)];
|
|
411
|
-
filePath = getFilePath(hostdirs[index], requrl);
|
|
412
|
-
fs.readFile(filePath, function (err, data) {
|
|
413
|
-
if (err)
|
|
414
|
-
tryRead(index + 1);
|
|
415
|
-
else
|
|
416
|
-
resolve({ resdata: data, filepath: filePath });
|
|
417
|
-
});
|
|
418
|
-
return [2 /*return*/];
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
};
|
|
422
|
-
tryRead();
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
// 启动HTTP服务
|
|
426
|
-
function startHTTPServer(hostdir) {
|
|
427
|
-
// 初始化服务配置
|
|
428
|
-
var hostcfg = $asai.hostconfig.hosts[hostdir];
|
|
429
|
-
try {
|
|
430
|
-
if (!$asai.servershttp[hostdir]) {
|
|
431
|
-
if (hostcfg.mimetypes) {
|
|
432
|
-
Object.assign(hostcfg.mimetypes, $asai.hostconfig.mimetypes);
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
hostcfg.mimetypes = $asai.hostconfig.mimetypes;
|
|
436
|
-
}
|
|
437
|
-
// 创建服务
|
|
438
|
-
var http_2 = getHTTPServer();
|
|
439
|
-
$asai.servershttp[hostdir] = http_2.AsCreateServer(function (req, res) {
|
|
440
|
-
if (checkHttpHeader(req)) {
|
|
441
|
-
if (req.url.startsWith("/sys")) {
|
|
442
|
-
sysWork(req, res, hostdir);
|
|
443
|
-
}
|
|
444
|
-
else if (req.url.startsWith("/api")) {
|
|
445
|
-
apiWork(req, res, hostdir);
|
|
446
|
-
}
|
|
447
|
-
else if (hostcfg.hostdirs) {
|
|
448
|
-
fsReadFile(hostcfg.hostdirs, req.url)
|
|
449
|
-
.then(function (resfile) {
|
|
450
|
-
res.writeHead(200, {
|
|
451
|
-
"Content-Encoding": "gzip",
|
|
452
|
-
"Content-Type": hostcfg.mimetypes[path.extname(resfile.filepath)] ||
|
|
453
|
-
"application/octet-stream",
|
|
454
|
-
"Cache-Control": "public, max-age=3600", // 客户端缓存1小时
|
|
455
|
-
});
|
|
456
|
-
// 提前处理压缩数据为.gz
|
|
457
|
-
fs.createReadStream("file.gz").pipe(res);
|
|
458
|
-
res.end(resfile.resdata);
|
|
459
|
-
})
|
|
460
|
-
.catch(function (err) {
|
|
461
|
-
if (err === 404) {
|
|
462
|
-
res.writeHead(404, {
|
|
463
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
464
|
-
});
|
|
465
|
-
res.end("File not found!");
|
|
466
|
-
}
|
|
467
|
-
else {
|
|
468
|
-
res.writeHead(500, {
|
|
469
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
470
|
-
});
|
|
471
|
-
res.end("".concat(err, " error!"));
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
res.writeHead(404, {
|
|
477
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
478
|
-
});
|
|
479
|
-
res.end("404");
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
else {
|
|
483
|
-
res.writeHead(502, {
|
|
484
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
485
|
-
});
|
|
486
|
-
res.end("502");
|
|
487
|
-
}
|
|
488
|
-
});
|
|
489
|
-
hostcfg.ws && createWSHost(hostdir); // 创建ws服务
|
|
490
|
-
// 启动服务
|
|
491
|
-
if (hostcfg.ip || $asai.hostconfig.ip) {
|
|
492
|
-
$asai.servershttp[hostdir].listen(hostcfg.port, hostcfg.ip || $asai.hostconfig.ip, function () {
|
|
493
|
-
console.log("[".concat(hostdir, "] Start At ").concat(getNowTime(), "."));
|
|
494
|
-
hostcfg.ws &&
|
|
495
|
-
console.log("\u001B[44;28mWS Server ".concat($asai.hostconfig.wstype +
|
|
496
|
-
(hostcfg.ip || $asai.hostconfig.ip), ":").concat(hostcfg.port, "\u001B[0m"));
|
|
497
|
-
console.log("\u001B[42;28mHTTP Server ".concat($asai.hostconfig.httptype +
|
|
498
|
-
(hostcfg.ip || $asai.hostconfig.ip), ":").concat(hostcfg.port, "\u001B[0m"));
|
|
499
|
-
console.log("================================================");
|
|
500
|
-
});
|
|
501
|
-
}
|
|
502
|
-
else {
|
|
503
|
-
$asai.servershttp[hostdir].listen(hostcfg.port, function () {
|
|
504
|
-
console.log("[".concat(hostdir, "] Start At ").concat(getNowTime(), "."));
|
|
505
|
-
hostcfg.ws &&
|
|
506
|
-
console.log("\u001B[41;28mWS Server".concat($asai.hostconfig.wstype, "localhost:").concat(hostcfg.port, "\u001B[0m"));
|
|
507
|
-
console.log("\u001B[42;28mHTTP Server ".concat($asai.hostconfig.httptype, "localhost:").concat(hostcfg.port, "\u001B[0m"));
|
|
508
|
-
console.log("================================================");
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
catch (err) {
|
|
514
|
-
console.log(666.303, err);
|
|
515
|
-
}
|
|
516
|
-
if ($asai.hostconfig.status.connectionshttp) {
|
|
517
|
-
// 记录http服务连接(先删除连接用户,再操作node服务,成功几率更大,但记录用户会造成变量变大)
|
|
518
|
-
$asai.servershttp[hostdir].on("connection", function (connection) {
|
|
519
|
-
if (!$asai.connectionshttp[hostdir]) {
|
|
520
|
-
$asai.connectionshttp[hostdir] = new Set();
|
|
521
|
-
}
|
|
522
|
-
$asai.connectionshttp[hostdir].add(connection);
|
|
523
|
-
// 处理关闭服务
|
|
524
|
-
connection.on("close", function () {
|
|
525
|
-
$asai.connectionshttp[hostdir].delete(connection);
|
|
526
|
-
});
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
return $asai.servershttp[hostdir];
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
};
|
package/AsaiHost.ts
DELETED
|
@@ -1,522 +0,0 @@
|
|
|
1
|
-
module.exports = ($asai: any, opt: any) => {
|
|
2
|
-
const { sysWork, apiWork, wsWork } = opt;
|
|
3
|
-
const fs: any = require("fs");
|
|
4
|
-
const path: any = require("path");
|
|
5
|
-
const url: any = require("url");
|
|
6
|
-
|
|
7
|
-
// 读取配置文件
|
|
8
|
-
if (!$asai.hostconfig?.ip) {
|
|
9
|
-
$asai.hostconfig.ip = getIp();
|
|
10
|
-
}
|
|
11
|
-
// 通过环境变量控制日志输出
|
|
12
|
-
// if (process.env.NODE_ENV === 'production') {
|
|
13
|
-
// console.log = () => {}; // 关闭调试日志
|
|
14
|
-
// }
|
|
15
|
-
console.log(`※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※`);
|
|
16
|
-
// 获取http或https的服务
|
|
17
|
-
// const http: any = require('http2');
|
|
18
|
-
const http: any = require("http");
|
|
19
|
-
const https: any = require("https");
|
|
20
|
-
// 获取当前时间
|
|
21
|
-
function getNowTime() {
|
|
22
|
-
const datanow: any = new Date();
|
|
23
|
-
return (
|
|
24
|
-
datanow.getMonth() +
|
|
25
|
-
1 +
|
|
26
|
-
"-" +
|
|
27
|
-
datanow.getDate() +
|
|
28
|
-
" " +
|
|
29
|
-
datanow.getHours() +
|
|
30
|
-
":" +
|
|
31
|
-
datanow.getMinutes() +
|
|
32
|
-
":" +
|
|
33
|
-
datanow.getSeconds() +
|
|
34
|
-
"." +
|
|
35
|
-
datanow.getMilliseconds()
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
// 获取本机IP地址
|
|
39
|
-
function getIp() {
|
|
40
|
-
const ifaces: any = require("os").networkInterfaces();
|
|
41
|
-
for (const el in ifaces) {
|
|
42
|
-
const iface: any = ifaces[el];
|
|
43
|
-
if (iface && iface.length) {
|
|
44
|
-
for (let i: number = 0; i < iface.length; i++) {
|
|
45
|
-
const elc: any = iface[i];
|
|
46
|
-
if (
|
|
47
|
-
elc.family === "IPv4" &&
|
|
48
|
-
elc.address !== "127.0.0.1" &&
|
|
49
|
-
!elc.internal
|
|
50
|
-
) {
|
|
51
|
-
return elc.address;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return "";
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function getHTTPServer() {
|
|
60
|
-
try {
|
|
61
|
-
if ($asai.hostconfig.httptype.includes("https")) {
|
|
62
|
-
https.AsCreateServer = (callback: any) => {
|
|
63
|
-
return https.createServer($asai.hostconfig.httpscert, callback);
|
|
64
|
-
};
|
|
65
|
-
return https;
|
|
66
|
-
} else {
|
|
67
|
-
http.AsCreateServer = http.createServer;
|
|
68
|
-
return http;
|
|
69
|
-
}
|
|
70
|
-
} catch (err: any) {
|
|
71
|
-
console.log(666.907, err);
|
|
72
|
-
http.AsCreateServer = http.createServer;
|
|
73
|
-
return http;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function getWsUserinfo(req: any) {
|
|
77
|
-
try {
|
|
78
|
-
const headers = Object.fromEntries(
|
|
79
|
-
Array.from({ length: req.rawHeaders.length / 2 }, (_, i) => [
|
|
80
|
-
req.rawHeaders[i * 2].toLowerCase(),
|
|
81
|
-
req.rawHeaders[i * 2 + 1],
|
|
82
|
-
])
|
|
83
|
-
);
|
|
84
|
-
const userinfo = headers["sec-websocket-protocol"]?.split("##");
|
|
85
|
-
return deUserInfo(userinfo);
|
|
86
|
-
} catch (err) {}
|
|
87
|
-
return null;
|
|
88
|
-
}
|
|
89
|
-
// Ws请求头校验
|
|
90
|
-
function checkWsHeader(req: any) {
|
|
91
|
-
req.Userinfo = getWsUserinfo(req);
|
|
92
|
-
console.log(666.2001, "WS", req.Userinfo[0]);
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
function getHttpUserinfo(req: any) {
|
|
96
|
-
try {
|
|
97
|
-
const headers = Object.fromEntries(
|
|
98
|
-
Array.from({ length: req.rawHeaders.length / 2 }, (_, i) => [
|
|
99
|
-
req.rawHeaders[i * 2].toLowerCase(),
|
|
100
|
-
req.rawHeaders[i * 2 + 1],
|
|
101
|
-
])
|
|
102
|
-
);
|
|
103
|
-
const userinfo = headers["userinfo"]?.split("##");
|
|
104
|
-
return deUserInfo(userinfo);
|
|
105
|
-
} catch (err) {}
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
// tcp请求头校验
|
|
109
|
-
function checkHttpHeader(req: any) {
|
|
110
|
-
req.Userinfo = getHttpUserinfo(req);
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
function deUserInfo(userinfo: any) {
|
|
114
|
-
if (userinfo[2]) {
|
|
115
|
-
userinfo[2] = $asai.$lib.AsCode.asdecode(
|
|
116
|
-
userinfo[2],
|
|
117
|
-
$asai.hostconfig.asaisn
|
|
118
|
-
);
|
|
119
|
-
userinfo[0] = $asai.$lib.AsCode.asdecode(userinfo[0], userinfo[2]);
|
|
120
|
-
userinfo[1] = $asai.$lib.AsCode.asdecode(userinfo[1], userinfo[2]);
|
|
121
|
-
}
|
|
122
|
-
return userinfo;
|
|
123
|
-
}
|
|
124
|
-
// 代理服务器
|
|
125
|
-
if ($asai.hostconfig?.proxyhosts) {
|
|
126
|
-
// 循环启动配置中的服务
|
|
127
|
-
Object.keys($asai.hostconfig.proxyhosts).forEach((el) => {
|
|
128
|
-
startProxyServer(el);
|
|
129
|
-
});
|
|
130
|
-
// 启动代理服务器
|
|
131
|
-
function startProxyServer(proxyhost: string) {
|
|
132
|
-
const proxycfg = $asai.hostconfig.proxyhosts[proxyhost];
|
|
133
|
-
if (!proxycfg.url && proxycfg.port) {
|
|
134
|
-
proxycfg.url =
|
|
135
|
-
$asai.hostconfig.httptype + $asai.hostconfig.ip + ":" + proxycfg.port;
|
|
136
|
-
}
|
|
137
|
-
if (proxycfg.url) {
|
|
138
|
-
const http = getHTTPServer();
|
|
139
|
-
const proxyServer = http.AsCreateServer((req: any, res: any) => {
|
|
140
|
-
// 启用Keep-Alive复用连接
|
|
141
|
-
const agent = new http.Agent({ keepAlive: true });
|
|
142
|
-
const forwardRequest = http.request(
|
|
143
|
-
{
|
|
144
|
-
agent: agent, // 复用连接池
|
|
145
|
-
method: req.method,
|
|
146
|
-
...url.parse(proxycfg.url + req.url),
|
|
147
|
-
},
|
|
148
|
-
(forwardRes: any) => {
|
|
149
|
-
// 设置响应头(可以选择性地转发原始响应头)
|
|
150
|
-
Object.keys(forwardRes.headers).forEach((key) => {
|
|
151
|
-
res.setHeader(key, forwardRes.headers[key]);
|
|
152
|
-
});
|
|
153
|
-
res.statusCode = forwardRes.statusCode;
|
|
154
|
-
console.log(666.001, getHttpUserinfo(req));
|
|
155
|
-
res.setHeader("Userinfo", getHttpUserinfo(req));
|
|
156
|
-
// 转发响应数据
|
|
157
|
-
req.pipe(forwardRequest); // 自动处理背压
|
|
158
|
-
forwardRes.pipe(res);
|
|
159
|
-
// forwardRes.pipe(res, { end: true }); // 手动数据传递
|
|
160
|
-
}
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// 处理转发请求的错误
|
|
164
|
-
forwardRequest.on("error", (err: any) => {
|
|
165
|
-
console.error("Error during forward request:", err);
|
|
166
|
-
res.writeHead(502); // Bad Gateway
|
|
167
|
-
res.end("Bad Gateway");
|
|
168
|
-
});
|
|
169
|
-
// 转发请求数据
|
|
170
|
-
req.pipe(forwardRequest, { end: true });
|
|
171
|
-
|
|
172
|
-
// 请求超时
|
|
173
|
-
forwardRequest.setTimeout(50000, () => {
|
|
174
|
-
forwardRequest.destroy();
|
|
175
|
-
res.writeHead(504);
|
|
176
|
-
res.end("Gateway Timeout");
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
if (proxycfg.proxyip) {
|
|
180
|
-
proxyServer.listen(
|
|
181
|
-
proxycfg.proxyport || $asai.hostconfig.proxyport,
|
|
182
|
-
proxycfg.proxyip,
|
|
183
|
-
() => {
|
|
184
|
-
console.log(`[${proxyhost}] Start At ${getNowTime()}.`);
|
|
185
|
-
console.log(
|
|
186
|
-
`\x1B[45;28mProxy Server ${$asai.hostconfig.httptype}${
|
|
187
|
-
proxycfg.proxyip
|
|
188
|
-
}:${proxycfg.proxyport || $asai.hostconfig.proxyport}\x1B[0m`
|
|
189
|
-
);
|
|
190
|
-
console.log(`================================================`);
|
|
191
|
-
}
|
|
192
|
-
);
|
|
193
|
-
} else {
|
|
194
|
-
proxyServer.listen(
|
|
195
|
-
proxycfg.proxyport || $asai.hostconfig.proxyport,
|
|
196
|
-
() => {
|
|
197
|
-
console.log(`[${proxyhost}] Start At ${getNowTime()}.`);
|
|
198
|
-
console.log(
|
|
199
|
-
`\x1B[45;28mProxy server ${
|
|
200
|
-
$asai.hostconfig.httptype
|
|
201
|
-
}localhost:${
|
|
202
|
-
proxycfg.proxyport || $asai.hostconfig.proxyport
|
|
203
|
-
}\x1B[0m`
|
|
204
|
-
);
|
|
205
|
-
console.log(`================================================`);
|
|
206
|
-
}
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// 网页与文件服务器
|
|
214
|
-
if ($asai.hostconfig?.hosts) {
|
|
215
|
-
$asai.startHTTPServer = startHTTPServer;
|
|
216
|
-
// 循环启动配置中的服务
|
|
217
|
-
Object.keys($asai.hostconfig.hosts).forEach((el) => {
|
|
218
|
-
startHTTPServer(el);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// 创建WS服务
|
|
222
|
-
function createWSHost(hostdir: string | number) {
|
|
223
|
-
try {
|
|
224
|
-
if (!$asai.serversws[hostdir]) {
|
|
225
|
-
const { WebSocket, WebSocketServer } = require("ws");
|
|
226
|
-
const wsopt = {};
|
|
227
|
-
// ws的配置项
|
|
228
|
-
$asai.serversws[hostdir] = new WebSocketServer({
|
|
229
|
-
server: $asai.servershttp[hostdir],
|
|
230
|
-
// 附加配置信息
|
|
231
|
-
perMessageDeflate: false, // 关闭压缩减少CPU开销
|
|
232
|
-
// perMessageDeflate: {
|
|
233
|
-
// zlibDeflateOptions: {
|
|
234
|
-
// // See zlib defaults.
|
|
235
|
-
// chunkSize: 1024,
|
|
236
|
-
// memLevel: 7,
|
|
237
|
-
// level: 3,
|
|
238
|
-
// },
|
|
239
|
-
// zlibInflateOptions: {
|
|
240
|
-
// chunkSize: 10 * 1024,
|
|
241
|
-
// },
|
|
242
|
-
// // Other options settable:
|
|
243
|
-
// clientNoContextTakeover: true, // Defaults to negotiated value.
|
|
244
|
-
// serverNoContextTakeover: true, // Defaults to negotiated value.
|
|
245
|
-
// serverMaxWindowBits: 10, // Defaults to negotiated value.
|
|
246
|
-
// // Below options specified as default values.
|
|
247
|
-
// concurrencyLimit: 10, // Limits zlib concurrency for perf.
|
|
248
|
-
// threshold: 1024, // Size (in bytes) below which messages
|
|
249
|
-
// // should not be compressed if context takeover is disabled.
|
|
250
|
-
// },
|
|
251
|
-
});
|
|
252
|
-
// 服务器ws服务关闭操作,清空定时器
|
|
253
|
-
function wsServerClose() {
|
|
254
|
-
if (
|
|
255
|
-
$asai.tasksws[hostdir] &&
|
|
256
|
-
typeof $asai.tasksws[hostdir] === "object"
|
|
257
|
-
) {
|
|
258
|
-
Object.values($asai.tasksws[hostdir]).forEach((el: any) => {
|
|
259
|
-
el && clearInterval(el);
|
|
260
|
-
});
|
|
261
|
-
$asai.tasksws[hostdir] = {};
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// 服务端异常错误关闭
|
|
266
|
-
$asai.serversws[hostdir].on("error", () => {
|
|
267
|
-
wsServerClose();
|
|
268
|
-
$asai.hostconfig.log && console.log(666.303, "WS Server error!");
|
|
269
|
-
});
|
|
270
|
-
// 服务端异常关闭
|
|
271
|
-
$asai.serversws[hostdir].on("close", () => {
|
|
272
|
-
wsServerClose();
|
|
273
|
-
$asai.hostconfig.log && console.log(666.301, "WS Server close!");
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
277
|
-
// 初始化记录ws服务连接
|
|
278
|
-
if (!$asai.connectionsws[hostdir]) {
|
|
279
|
-
$asai.connectionsws[hostdir] = new WeakMap();
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// 服务被连接后...
|
|
283
|
-
$asai.serversws[hostdir].on("connection", (ws: any, req: any) => {
|
|
284
|
-
if (!$asai.tasksws[hostdir]) {
|
|
285
|
-
$asai.tasksws[hostdir] = {};
|
|
286
|
-
}
|
|
287
|
-
if (!ws?.tasksws) {
|
|
288
|
-
ws.tasksws = {};
|
|
289
|
-
}
|
|
290
|
-
if (checkWsHeader(req)) {
|
|
291
|
-
$asai.hostconfig.log &&
|
|
292
|
-
console.log(666.2002, req.Userinfo, "wsClient connection!");
|
|
293
|
-
function closeWs() {
|
|
294
|
-
ws.close();
|
|
295
|
-
}
|
|
296
|
-
if (
|
|
297
|
-
$asai.hostconfig.status.connectionsws &&
|
|
298
|
-
(!req.Userinfo[0] ||
|
|
299
|
-
!req.Userinfo[2] ||
|
|
300
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]])
|
|
301
|
-
) {
|
|
302
|
-
// 连接用户信息不符合条件,已存在同账户的登录
|
|
303
|
-
closeWs();
|
|
304
|
-
} else {
|
|
305
|
-
$asai.hostconfig.log && console.log(666.2006, "ok!");
|
|
306
|
-
// 正常登录
|
|
307
|
-
const [us, lv, tk] = req.Userinfo || [];
|
|
308
|
-
ws.Userinfo = { us, lv, tk }; // 赋值给ws
|
|
309
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
310
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]] = ws;
|
|
311
|
-
}
|
|
312
|
-
// 发送消息
|
|
313
|
-
$asai.serversws[hostdir].sendws = (
|
|
314
|
-
msg: any,
|
|
315
|
-
type: number,
|
|
316
|
-
curws: any
|
|
317
|
-
) => {
|
|
318
|
-
if (type) {
|
|
319
|
-
// 广播消息
|
|
320
|
-
// wsopt.ulen = 0;
|
|
321
|
-
$asai.serversws[hostdir].clients.forEach((client: any) => {
|
|
322
|
-
// wsopt.ulen++;
|
|
323
|
-
if (
|
|
324
|
-
(type == 2 || client !== curws) &&
|
|
325
|
-
client.readyState == WebSocket.OPEN
|
|
326
|
-
) {
|
|
327
|
-
client.send(msg);
|
|
328
|
-
}
|
|
329
|
-
console.info(666.801, client.Userinfo);
|
|
330
|
-
});
|
|
331
|
-
// $asai.hostconfig.log &&
|
|
332
|
-
// console.log(666.808, "wsClient Public!", wsopt.ulen);
|
|
333
|
-
} else {
|
|
334
|
-
// api方式回复消息
|
|
335
|
-
curws.send(msg);
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
//监听客户端发来的消息
|
|
340
|
-
ws.on("message", (msg: any) => {
|
|
341
|
-
wsWork(msg, ws, hostdir, req);
|
|
342
|
-
});
|
|
343
|
-
// 客户端关闭
|
|
344
|
-
ws.on("close", (err: any) => {
|
|
345
|
-
$asai.hostconfig.log &&
|
|
346
|
-
console.log(
|
|
347
|
-
666.103,
|
|
348
|
-
req.Userinfo[0] + " wsClient close!",
|
|
349
|
-
err
|
|
350
|
-
);
|
|
351
|
-
if ($asai.hostconfig.status.connectionsws) {
|
|
352
|
-
// 关闭点对点客户端的任务
|
|
353
|
-
if (ws.tasksws && typeof ws.tasksws === "object") {
|
|
354
|
-
Object.values(ws.tasksws).forEach((el: any) => {
|
|
355
|
-
el && clearInterval(el);
|
|
356
|
-
});
|
|
357
|
-
ws.tasksws = null;
|
|
358
|
-
}
|
|
359
|
-
if (
|
|
360
|
-
req.Userinfo[0] &&
|
|
361
|
-
$asai.connectionsws[hostdir][req.Userinfo[0]]
|
|
362
|
-
) {
|
|
363
|
-
delete $asai.connectionsws[hostdir][req.Userinfo[0]];
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
} catch (err) {}
|
|
372
|
-
return $asai.serversws[hostdir];
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
// 请求的文件相对路径
|
|
376
|
-
function getFilePath(hostdir: string, requrl: string) {
|
|
377
|
-
let filePath = "" + requrl;
|
|
378
|
-
if (filePath == "/" || filePath == "") {
|
|
379
|
-
filePath = "/index.html";
|
|
380
|
-
}
|
|
381
|
-
if (hostdir == "home") {
|
|
382
|
-
filePath = "." + filePath;
|
|
383
|
-
} else {
|
|
384
|
-
filePath = "./" + hostdir + filePath;
|
|
385
|
-
}
|
|
386
|
-
return filePath;
|
|
387
|
-
}
|
|
388
|
-
// 读取服务器上文件
|
|
389
|
-
function fsReadFile(hostdirs: any, requrl: any) {
|
|
390
|
-
return new Promise((resolve, reject) => {
|
|
391
|
-
// 尝试顺序读取多个路径
|
|
392
|
-
const tryRead = async (index = 0) => {
|
|
393
|
-
if (index >= hostdirs.length) return reject(404);
|
|
394
|
-
const filePath = getFilePath(hostdirs[index], requrl);
|
|
395
|
-
fs.readFile(filePath, (err: any, data: any) => {
|
|
396
|
-
if (err) tryRead(index + 1);
|
|
397
|
-
else resolve({ resdata: data, filepath: filePath });
|
|
398
|
-
});
|
|
399
|
-
};
|
|
400
|
-
tryRead();
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
// 启动HTTP服务
|
|
404
|
-
function startHTTPServer(hostdir: string) {
|
|
405
|
-
// 初始化服务配置
|
|
406
|
-
const hostcfg = $asai.hostconfig.hosts[hostdir];
|
|
407
|
-
try {
|
|
408
|
-
if (!$asai.servershttp[hostdir]) {
|
|
409
|
-
if (hostcfg.mimetypes) {
|
|
410
|
-
Object.assign(hostcfg.mimetypes, $asai.hostconfig.mimetypes);
|
|
411
|
-
} else {
|
|
412
|
-
hostcfg.mimetypes = $asai.hostconfig.mimetypes;
|
|
413
|
-
}
|
|
414
|
-
// 创建服务
|
|
415
|
-
const http = getHTTPServer();
|
|
416
|
-
$asai.servershttp[hostdir] = http.AsCreateServer(
|
|
417
|
-
(req: any, res: any) => {
|
|
418
|
-
if (checkHttpHeader(req)) {
|
|
419
|
-
if (req.url.startsWith("/sys")) {
|
|
420
|
-
sysWork(req, res, hostdir);
|
|
421
|
-
} else if (req.url.startsWith("/api")) {
|
|
422
|
-
apiWork(req, res, hostdir);
|
|
423
|
-
} else if (hostcfg.hostdirs) {
|
|
424
|
-
fsReadFile(hostcfg.hostdirs, req.url)
|
|
425
|
-
.then((resfile: any) => {
|
|
426
|
-
res.writeHead(200, {
|
|
427
|
-
"Content-Encoding": "gzip",
|
|
428
|
-
"Content-Type":
|
|
429
|
-
hostcfg.mimetypes[path.extname(resfile.filepath)] ||
|
|
430
|
-
"application/octet-stream",
|
|
431
|
-
"Cache-Control": "public, max-age=3600", // 客户端缓存1小时
|
|
432
|
-
});
|
|
433
|
-
// 提前处理压缩数据为.gz
|
|
434
|
-
fs.createReadStream("file.gz").pipe(res);
|
|
435
|
-
res.end(resfile.resdata);
|
|
436
|
-
})
|
|
437
|
-
.catch((err) => {
|
|
438
|
-
if (err === 404) {
|
|
439
|
-
res.writeHead(404, {
|
|
440
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
441
|
-
});
|
|
442
|
-
res.end(`File not found!`);
|
|
443
|
-
} else {
|
|
444
|
-
res.writeHead(500, {
|
|
445
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
446
|
-
});
|
|
447
|
-
res.end(`${err} error!`);
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
} else {
|
|
451
|
-
res.writeHead(404, {
|
|
452
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
453
|
-
});
|
|
454
|
-
res.end(`404`);
|
|
455
|
-
}
|
|
456
|
-
} else {
|
|
457
|
-
res.writeHead(502, {
|
|
458
|
-
"Content-Type": "text/plain; charset=utf-8",
|
|
459
|
-
});
|
|
460
|
-
res.end(`502`);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
);
|
|
464
|
-
hostcfg.ws && createWSHost(hostdir); // 创建ws服务
|
|
465
|
-
// 启动服务
|
|
466
|
-
if (hostcfg.ip || $asai.hostconfig.ip) {
|
|
467
|
-
$asai.servershttp[hostdir].listen(
|
|
468
|
-
hostcfg.port,
|
|
469
|
-
hostcfg.ip || $asai.hostconfig.ip,
|
|
470
|
-
() => {
|
|
471
|
-
console.log(`[${hostdir}] Start At ${getNowTime()}.`);
|
|
472
|
-
hostcfg.ws &&
|
|
473
|
-
console.log(
|
|
474
|
-
`\x1B[44;28mWS Server ${
|
|
475
|
-
$asai.hostconfig.wstype +
|
|
476
|
-
(hostcfg.ip || $asai.hostconfig.ip)
|
|
477
|
-
}:${hostcfg.port}\x1B[0m`
|
|
478
|
-
);
|
|
479
|
-
console.log(
|
|
480
|
-
`\x1B[42;28mHTTP Server ${
|
|
481
|
-
$asai.hostconfig.httptype +
|
|
482
|
-
(hostcfg.ip || $asai.hostconfig.ip)
|
|
483
|
-
}:${hostcfg.port}\x1B[0m`
|
|
484
|
-
);
|
|
485
|
-
console.log(`================================================`);
|
|
486
|
-
}
|
|
487
|
-
);
|
|
488
|
-
} else {
|
|
489
|
-
$asai.servershttp[hostdir].listen(hostcfg.port, () => {
|
|
490
|
-
console.log(`[${hostdir}] Start At ${getNowTime()}.`);
|
|
491
|
-
hostcfg.ws &&
|
|
492
|
-
console.log(
|
|
493
|
-
`\x1B[41;28mWS Server${$asai.hostconfig.wstype}localhost:${hostcfg.port}\x1B[0m`
|
|
494
|
-
);
|
|
495
|
-
console.log(
|
|
496
|
-
`\x1B[42;28mHTTP Server ${$asai.hostconfig.httptype}localhost:${hostcfg.port}\x1B[0m`
|
|
497
|
-
);
|
|
498
|
-
console.log(`================================================`);
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
} catch (err) {
|
|
503
|
-
console.log(666.303, err);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
if ($asai.hostconfig.status.connectionshttp) {
|
|
507
|
-
// 记录http服务连接(先删除连接用户,再操作node服务,成功几率更大,但记录用户会造成变量变大)
|
|
508
|
-
$asai.servershttp[hostdir].on("connection", (connection: any) => {
|
|
509
|
-
if (!$asai.connectionshttp[hostdir]) {
|
|
510
|
-
$asai.connectionshttp[hostdir] = new Set();
|
|
511
|
-
}
|
|
512
|
-
$asai.connectionshttp[hostdir].add(connection);
|
|
513
|
-
// 处理关闭服务
|
|
514
|
-
connection.on("close", () => {
|
|
515
|
-
$asai.connectionshttp[hostdir].delete(connection);
|
|
516
|
-
});
|
|
517
|
-
});
|
|
518
|
-
}
|
|
519
|
-
return $asai.servershttp[hostdir];
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(()=>{var __webpack_modules__={642:function(e,t,s){var r=this&&this.__assign||function(){r=Object.assign||function(e){for(var t,s=1,r=arguments.length;s<r;s++){t=arguments[s];for(var n in t)if(Object.prototype.hasOwnProperty.call(t,n))e[n]=t[n]}return e};return r.apply(this,arguments)};var n=this&&this.__awaiter||function(e,t,s,r){function adopt(e){return e instanceof s?e:new s((function(t){t(e)}))}return new(s||(s=Promise))((function(s,n){function fulfilled(e){try{step(r.next(e))}catch(e){n(e)}}function rejected(e){try{step(r["throw"](e))}catch(e){n(e)}}function step(e){e.done?s(e.value):adopt(e.value).then(fulfilled,rejected)}step((r=r.apply(e,t||[])).next())}))};var o=this&&this.__generator||function(e,t){var s={label:0,sent:function(){if(o[0]&1)throw o[1];return o[1]},trys:[],ops:[]},r,n,o,i=Object.create((typeof Iterator==="function"?Iterator:Object).prototype);return i.next=verb(0),i["throw"]=verb(1),i["return"]=verb(2),typeof Symbol==="function"&&(i[Symbol.iterator]=function(){return this}),i;function verb(e){return function(t){return step([e,t])}}function step(a){if(r)throw new TypeError("Generator is already executing.");while(i&&(i=0,a[0]&&(s=0)),s)try{if(r=1,n&&(o=a[0]&2?n["return"]:a[0]?n["throw"]||((o=n["return"])&&o.call(n),0):n.next)&&!(o=o.call(n,a[1])).done)return o;if(n=0,o)a=[a[0]&2,o.value];switch(a[0]){case 0:case 1:o=a;break;case 4:s.label++;return{value:a[1],done:false};case 5:s.label++;n=a[1];a=[0];continue;case 7:a=s.ops.pop();s.trys.pop();continue;default:if(!(o=s.trys,o=o.length>0&&o[o.length-1])&&(a[0]===6||a[0]===2)){s=0;continue}if(a[0]===3&&(!o||a[1]>o[0]&&a[1]<o[3])){s.label=a[1];break}if(a[0]===6&&s.label<o[1]){s.label=o[1];o=a;break}if(o&&s.label<o[2]){s.label=o[2];s.ops.push(a);break}if(o[2])s.ops.pop();s.trys.pop();continue}a=t.call(e,s)}catch(e){a=[6,e];n=0}finally{r=o=0}if(a[0]&5)throw a[1];return{value:a[0]?a[1]:void 0,done:true}}};var i=this&&this.__spreadArray||function(e,t,s){if(s||arguments.length===2)for(var r=0,n=t.length,o;r<n;r++){if(o||!(r in t)){if(!o)o=Array.prototype.slice.call(t,0,r);o[r]=t[r]}}return e.concat(o||Array.prototype.slice.call(t))};e.exports=function(e,t){var a,c,l;var f=t.sysWork,h=t.apiWork,u=t.wsWork;var d=s(896);var p=s(928);var _=s(16);if(!((a=e.hostconfig)===null||a===void 0?void 0:a.ip)){e.hostconfig.ip=getIp()}console.log("※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※");var m=s(611);var b=s(692);function getNowTime(){var e=new Date;return e.getMonth()+1+"-"+e.getDate()+" "+e.getHours()+":"+e.getMinutes()+":"+e.getSeconds()+"."+e.getMilliseconds()}function getIp(){var e=s(857).networkInterfaces();for(var t in e){var r=e[t];if(r&&r.length){for(var n=0;n<r.length;n++){var o=r[n];if(o.family==="IPv4"&&o.address!=="127.0.0.1"&&!o.internal){return o.address}}}}return""}function getHTTPServer(){try{if(e.hostconfig.httptype.includes("https")){b.AsCreateServer=function(t){return b.createServer(e.hostconfig.httpscert,t)};return b}else{m.AsCreateServer=m.createServer;return m}}catch(e){console.log(666.907,e);m.AsCreateServer=m.createServer;return m}}function getWsUserinfo(e){var t;try{var s=Object.fromEntries(Array.from({length:e.rawHeaders.length/2},(function(t,s){return[e.rawHeaders[s*2].toLowerCase(),e.rawHeaders[s*2+1]]})));var r=(t=s["sec-websocket-protocol"])===null||t===void 0?void 0:t.split("##");return deUserInfo(r)}catch(e){}return null}function checkWsHeader(e){e.Userinfo=getWsUserinfo(e);console.log(666.2001,"WS",e.Userinfo[0]);return true}function getHttpUserinfo(e){var t;try{var s=Object.fromEntries(Array.from({length:e.rawHeaders.length/2},(function(t,s){return[e.rawHeaders[s*2].toLowerCase(),e.rawHeaders[s*2+1]]})));var r=(t=s["userinfo"])===null||t===void 0?void 0:t.split("##");return deUserInfo(r)}catch(e){}return null}function checkHttpHeader(e){e.Userinfo=getHttpUserinfo(e);return true}function deUserInfo(t){if(t[2]){t[2]=e.$lib.AsCode.asdecode(t[2],e.hostconfig.asaisn);t[0]=e.$lib.AsCode.asdecode(t[0],t[2]);t[1]=e.$lib.AsCode.asdecode(t[1],t[2])}return t}if((c=e.hostconfig)===null||c===void 0?void 0:c.proxyhosts){Object.keys(e.hostconfig.proxyhosts).forEach((function(e){startProxyServer(e)}));function startProxyServer(t){var s=e.hostconfig.proxyhosts[t];if(!s.url&&s.port){s.url=e.hostconfig.httptype+e.hostconfig.ip+":"+s.port}if(s.url){var n=getHTTPServer();var o=n.AsCreateServer((function(e,t){var o=new n.Agent({keepAlive:true});var i=n.request(r({agent:o,method:e.method},_.parse(s.url+e.url)),(function(s){Object.keys(s.headers).forEach((function(e){t.setHeader(e,s.headers[e])}));t.statusCode=s.statusCode;console.log(666.001,getHttpUserinfo(e));t.setHeader("Userinfo",getHttpUserinfo(e));e.pipe(i);s.pipe(t)}));i.on("error",(function(e){console.error("Error during forward request:",e);t.writeHead(502);t.end("Bad Gateway")}));e.pipe(i,{end:true});i.setTimeout(5e4,(function(){i.destroy();t.writeHead(504);t.end("Gateway Timeout")}))}));if(s.proxyip){o.listen(s.proxyport||e.hostconfig.proxyport,s.proxyip,(function(){console.log("[".concat(t,"] Start At ").concat(getNowTime(),"."));console.log("[45;28mProxy Server ".concat(e.hostconfig.httptype).concat(s.proxyip,":").concat(s.proxyport||e.hostconfig.proxyport,"[0m"));console.log("================================================")}))}else{o.listen(s.proxyport||e.hostconfig.proxyport,(function(){console.log("[".concat(t,"] Start At ").concat(getNowTime(),"."));console.log("[45;28mProxy server ".concat(e.hostconfig.httptype,"localhost:").concat(s.proxyport||e.hostconfig.proxyport,"[0m"));console.log("================================================")}))}}}}if((l=e.hostconfig)===null||l===void 0?void 0:l.hosts){e.startHTTPServer=startHTTPServer;Object.keys(e.hostconfig.hosts).forEach((function(e){startHTTPServer(e)}));function createWSHost(t){try{if(!e.serversws[t]){var r=s(313),n=r.WebSocket,o=r.WebSocketServer;var i={};e.serversws[t]=new o({server:e.servershttp[t],perMessageDeflate:false});function wsServerClose(){if(e.tasksws[t]&&typeof e.tasksws[t]==="object"){Object.values(e.tasksws[t]).forEach((function(e){e&&clearInterval(e)}));e.tasksws[t]={}}}e.serversws[t].on("error",(function(){wsServerClose();e.hostconfig.log&&console.log(666.303,"WS Server error!")}));e.serversws[t].on("close",(function(){wsServerClose();e.hostconfig.log&&console.log(666.301,"WS Server close!")}));if(e.hostconfig.status.connectionsws){if(!e.connectionsws[t]){e.connectionsws[t]=new WeakMap}}e.serversws[t].on("connection",(function(s,r){if(!e.tasksws[t]){e.tasksws[t]={}}if(!(s===null||s===void 0?void 0:s.tasksws)){s.tasksws={}}if(checkWsHeader(r)){e.hostconfig.log&&console.log(666.2002,r.Userinfo,"wsClient connection!");function closeWs(){s.close()}if(e.hostconfig.status.connectionsws&&(!r.Userinfo[0]||!r.Userinfo[2]||e.connectionsws[t][r.Userinfo[0]])){closeWs()}else{e.hostconfig.log&&console.log(666.2006,"ok!");var o=r.Userinfo||[],i=o[0],a=o[1],c=o[2];s.Userinfo={us:i,lv:a,tk:c};if(e.hostconfig.status.connectionsws){e.connectionsws[t][r.Userinfo[0]]=s}e.serversws[t].sendws=function(s,r,o){if(r){e.serversws[t].clients.forEach((function(e){if((r==2||e!==o)&&e.readyState==n.OPEN){e.send(s)}console.info(666.801,e.Userinfo)}))}else{o.send(s)}};s.on("message",(function(e){u(e,s,t,r)}));s.on("close",(function(n){e.hostconfig.log&&console.log(666.103,r.Userinfo[0]+" wsClient close!",n);if(e.hostconfig.status.connectionsws){if(s.tasksws&&typeof s.tasksws==="object"){Object.values(s.tasksws).forEach((function(e){e&&clearInterval(e)}));s.tasksws=null}if(r.Userinfo[0]&&e.connectionsws[t][r.Userinfo[0]]){delete e.connectionsws[t][r.Userinfo[0]]}}}))}}}))}}catch(a){}return e.serversws[t]}function getFilePath(e,t){var s=""+t;if(s=="/"||s==""){s="/index.html"}if(e=="home"){s="."+s}else{s="./"+e+s}return s}function fsReadFile(e,t){var s=this;return new Promise((function(r,a){var tryRead=function(){var c=[];for(var l=0;l<arguments.length;l++){c[l]=arguments[l]}return n(s,i([],c,true),void 0,(function(s){var n;if(s===void 0){s=0}return o(this,(function(o){if(s>=e.length)return[2,a(404)];n=getFilePath(e[s],t);d.readFile(n,(function(e,t){if(e)tryRead(s+1);else r({resdata:t,filepath:n})}));return[2]}))}))};tryRead()}))}function startHTTPServer(t){var s=e.hostconfig.hosts[t];try{if(!e.servershttp[t]){if(s.mimetypes){Object.assign(s.mimetypes,e.hostconfig.mimetypes)}else{s.mimetypes=e.hostconfig.mimetypes}var r=getHTTPServer();e.servershttp[t]=r.AsCreateServer((function(e,r){if(checkHttpHeader(e)){if(e.url.startsWith("/sys")){f(e,r,t)}else if(e.url.startsWith("/api")){h(e,r,t)}else if(s.hostdirs){fsReadFile(s.hostdirs,e.url).then((function(e){r.writeHead(200,{"Content-Encoding":"gzip","Content-Type":s.mimetypes[p.extname(e.filepath)]||"application/octet-stream","Cache-Control":"public, max-age=3600"});d.createReadStream("file.gz").pipe(r);r.end(e.resdata)})).catch((function(e){if(e===404){r.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"});r.end("File not found!")}else{r.writeHead(500,{"Content-Type":"text/plain; charset=utf-8"});r.end("".concat(e," error!"))}}))}else{r.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"});r.end("404")}}else{r.writeHead(502,{"Content-Type":"text/plain; charset=utf-8"});r.end("502")}}));s.ws&&createWSHost(t);if(s.ip||e.hostconfig.ip){e.servershttp[t].listen(s.port,s.ip||e.hostconfig.ip,(function(){console.log("[".concat(t,"] Start At ").concat(getNowTime(),"."));s.ws&&console.log("[44;28mWS Server ".concat(e.hostconfig.wstype+(s.ip||e.hostconfig.ip),":").concat(s.port,"[0m"));console.log("[42;28mHTTP Server ".concat(e.hostconfig.httptype+(s.ip||e.hostconfig.ip),":").concat(s.port,"[0m"));console.log("================================================")}))}else{e.servershttp[t].listen(s.port,(function(){console.log("[".concat(t,"] Start At ").concat(getNowTime(),"."));s.ws&&console.log("[41;28mWS Server".concat(e.hostconfig.wstype,"localhost:").concat(s.port,"[0m"));console.log("[42;28mHTTP Server ".concat(e.hostconfig.httptype,"localhost:").concat(s.port,"[0m"));console.log("================================================")}))}}}catch(e){console.log(666.303,e)}if(e.hostconfig.status.connectionshttp){e.servershttp[t].on("connection",(function(s){if(!e.connectionshttp[t]){e.connectionshttp[t]=new Set}e.connectionshttp[t].add(s);s.on("close",(function(){e.connectionshttp[t].delete(s)}))}))}return e.servershttp[t]}}}},313:(e,t,s)=>{"use strict";const r=s(102);r.createWebSocketStream=s(597);r.Server=s(672);r.Receiver=s(500);r.Sender=s(124);r.WebSocket=r;r.WebSocketServer=r.Server;e.exports=r},356:(e,t,s)=>{"use strict";const{EMPTY_BUFFER:r}=s(112);const n=Buffer[Symbol.species];function concat(e,t){if(e.length===0)return r;if(e.length===1)return e[0];const s=Buffer.allocUnsafe(t);let o=0;for(let t=0;t<e.length;t++){const r=e[t];s.set(r,o);o+=r.length}if(o<t){return new n(s.buffer,s.byteOffset,o)}return s}function _mask(e,t,s,r,n){for(let o=0;o<n;o++){s[r+o]=e[o]^t[o&3]}}function _unmask(e,t){for(let s=0;s<e.length;s++){e[s]^=t[s&3]}}function toArrayBuffer(e){if(e.length===e.buffer.byteLength){return e.buffer}return e.buffer.slice(e.byteOffset,e.byteOffset+e.length)}function toBuffer(e){toBuffer.readOnly=true;if(Buffer.isBuffer(e))return e;let t;if(e instanceof ArrayBuffer){t=new n(e)}else if(ArrayBuffer.isView(e)){t=new n(e.buffer,e.byteOffset,e.byteLength)}else{t=Buffer.from(e);toBuffer.readOnly=false}return t}e.exports={concat:concat,mask:_mask,toArrayBuffer:toArrayBuffer,toBuffer:toBuffer,unmask:_unmask};if(!process.env.WS_NO_BUFFER_UTIL){try{const t=s(941);e.exports.mask=function(e,s,r,n,o){if(o<48)_mask(e,s,r,n,o);else t.mask(e,s,r,n,o)};e.exports.unmask=function(e,s){if(e.length<32)_unmask(e,s);else t.unmask(e,s)}}catch(e){}}},112:e=>{"use strict";const t=["nodebuffer","arraybuffer","fragments"];const s=typeof Blob!=="undefined";if(s)t.push("blob");e.exports={BINARY_TYPES:t,EMPTY_BUFFER:Buffer.alloc(0),GUID:"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",hasBlob:s,kForOnEventAttribute:Symbol("kIsForOnEventAttribute"),kListener:Symbol("kListener"),kStatusCode:Symbol("status-code"),kWebSocket:Symbol("websocket"),NOOP:()=>{}}},139:(e,t,s)=>{"use strict";const{kForOnEventAttribute:r,kListener:n}=s(112);const o=Symbol("kCode");const i=Symbol("kData");const a=Symbol("kError");const c=Symbol("kMessage");const l=Symbol("kReason");const f=Symbol("kTarget");const h=Symbol("kType");const u=Symbol("kWasClean");class Event{constructor(e){this[f]=null;this[h]=e}get target(){return this[f]}get type(){return this[h]}}Object.defineProperty(Event.prototype,"target",{enumerable:true});Object.defineProperty(Event.prototype,"type",{enumerable:true});class CloseEvent extends Event{constructor(e,t={}){super(e);this[o]=t.code===undefined?0:t.code;this[l]=t.reason===undefined?"":t.reason;this[u]=t.wasClean===undefined?false:t.wasClean}get code(){return this[o]}get reason(){return this[l]}get wasClean(){return this[u]}}Object.defineProperty(CloseEvent.prototype,"code",{enumerable:true});Object.defineProperty(CloseEvent.prototype,"reason",{enumerable:true});Object.defineProperty(CloseEvent.prototype,"wasClean",{enumerable:true});class ErrorEvent extends Event{constructor(e,t={}){super(e);this[a]=t.error===undefined?null:t.error;this[c]=t.message===undefined?"":t.message}get error(){return this[a]}get message(){return this[c]}}Object.defineProperty(ErrorEvent.prototype,"error",{enumerable:true});Object.defineProperty(ErrorEvent.prototype,"message",{enumerable:true});class MessageEvent extends Event{constructor(e,t={}){super(e);this[i]=t.data===undefined?null:t.data}get data(){return this[i]}}Object.defineProperty(MessageEvent.prototype,"data",{enumerable:true});const d={addEventListener(e,t,s={}){for(const o of this.listeners(e)){if(!s[r]&&o[n]===t&&!o[r]){return}}let o;if(e==="message"){o=function onMessage(e,s){const r=new MessageEvent("message",{data:s?e:e.toString()});r[f]=this;callListener(t,this,r)}}else if(e==="close"){o=function onClose(e,s){const r=new CloseEvent("close",{code:e,reason:s.toString(),wasClean:this._closeFrameReceived&&this._closeFrameSent});r[f]=this;callListener(t,this,r)}}else if(e==="error"){o=function onError(e){const s=new ErrorEvent("error",{error:e,message:e.message});s[f]=this;callListener(t,this,s)}}else if(e==="open"){o=function onOpen(){const e=new Event("open");e[f]=this;callListener(t,this,e)}}else{return}o[r]=!!s[r];o[n]=t;if(s.once){this.once(e,o)}else{this.on(e,o)}},removeEventListener(e,t){for(const s of this.listeners(e)){if(s[n]===t&&!s[r]){this.removeListener(e,s);break}}}};e.exports={CloseEvent:CloseEvent,ErrorEvent:ErrorEvent,Event:Event,EventTarget:d,MessageEvent:MessageEvent};function callListener(e,t,s){if(typeof e==="object"&&e.handleEvent){e.handleEvent.call(e,s)}else{e.call(t,s)}}},731:(e,t,s)=>{"use strict";const{tokenChars:r}=s(754);function push(e,t,s){if(e[t]===undefined)e[t]=[s];else e[t].push(s)}function parse(e){const t=Object.create(null);let s=Object.create(null);let n=false;let o=false;let i=false;let a;let c;let l=-1;let f=-1;let h=-1;let u=0;for(;u<e.length;u++){f=e.charCodeAt(u);if(a===undefined){if(h===-1&&r[f]===1){if(l===-1)l=u}else if(u!==0&&(f===32||f===9)){if(h===-1&&l!==-1)h=u}else if(f===59||f===44){if(l===-1){throw new SyntaxError(`Unexpected character at index ${u}`)}if(h===-1)h=u;const r=e.slice(l,h);if(f===44){push(t,r,s);s=Object.create(null)}else{a=r}l=h=-1}else{throw new SyntaxError(`Unexpected character at index ${u}`)}}else if(c===undefined){if(h===-1&&r[f]===1){if(l===-1)l=u}else if(f===32||f===9){if(h===-1&&l!==-1)h=u}else if(f===59||f===44){if(l===-1){throw new SyntaxError(`Unexpected character at index ${u}`)}if(h===-1)h=u;push(s,e.slice(l,h),true);if(f===44){push(t,a,s);s=Object.create(null);a=undefined}l=h=-1}else if(f===61&&l!==-1&&h===-1){c=e.slice(l,u);l=h=-1}else{throw new SyntaxError(`Unexpected character at index ${u}`)}}else{if(o){if(r[f]!==1){throw new SyntaxError(`Unexpected character at index ${u}`)}if(l===-1)l=u;else if(!n)n=true;o=false}else if(i){if(r[f]===1){if(l===-1)l=u}else if(f===34&&l!==-1){i=false;h=u}else if(f===92){o=true}else{throw new SyntaxError(`Unexpected character at index ${u}`)}}else if(f===34&&e.charCodeAt(u-1)===61){i=true}else if(h===-1&&r[f]===1){if(l===-1)l=u}else if(l!==-1&&(f===32||f===9)){if(h===-1)h=u}else if(f===59||f===44){if(l===-1){throw new SyntaxError(`Unexpected character at index ${u}`)}if(h===-1)h=u;let r=e.slice(l,h);if(n){r=r.replace(/\\/g,"");n=false}push(s,c,r);if(f===44){push(t,a,s);s=Object.create(null);a=undefined}c=undefined;l=h=-1}else{throw new SyntaxError(`Unexpected character at index ${u}`)}}}if(l===-1||i||f===32||f===9){throw new SyntaxError("Unexpected end of input")}if(h===-1)h=u;const d=e.slice(l,h);if(a===undefined){push(t,d,s)}else{if(c===undefined){push(s,d,true)}else if(n){push(s,c,d.replace(/\\/g,""))}else{push(s,c,d)}push(t,a,s)}return t}function format(e){return Object.keys(e).map((t=>{let s=e[t];if(!Array.isArray(s))s=[s];return s.map((e=>[t].concat(Object.keys(e).map((t=>{let s=e[t];if(!Array.isArray(s))s=[s];return s.map((e=>e===true?t:`${t}=${e}`)).join("; ")}))).join("; "))).join(", ")})).join(", ")}e.exports={format:format,parse:parse}},37:e=>{"use strict";const t=Symbol("kDone");const s=Symbol("kRun");class Limiter{constructor(e){this[t]=()=>{this.pending--;this[s]()};this.concurrency=e||Infinity;this.jobs=[];this.pending=0}add(e){this.jobs.push(e);this[s]()}[s](){if(this.pending===this.concurrency)return;if(this.jobs.length){const e=this.jobs.shift();this.pending++;e(this[t])}}}e.exports=Limiter},933:(e,t,s)=>{"use strict";const r=s(106);const n=s(356);const o=s(37);const{kStatusCode:i}=s(112);const a=Buffer[Symbol.species];const c=Buffer.from([0,0,255,255]);const l=Symbol("permessage-deflate");const f=Symbol("total-length");const h=Symbol("callback");const u=Symbol("buffers");const d=Symbol("error");let p;class PerMessageDeflate{constructor(e,t,s){this._maxPayload=s|0;this._options=e||{};this._threshold=this._options.threshold!==undefined?this._options.threshold:1024;this._isServer=!!t;this._deflate=null;this._inflate=null;this.params=null;if(!p){const e=this._options.concurrencyLimit!==undefined?this._options.concurrencyLimit:10;p=new o(e)}}static get extensionName(){return"permessage-deflate"}offer(){const e={};if(this._options.serverNoContextTakeover){e.server_no_context_takeover=true}if(this._options.clientNoContextTakeover){e.client_no_context_takeover=true}if(this._options.serverMaxWindowBits){e.server_max_window_bits=this._options.serverMaxWindowBits}if(this._options.clientMaxWindowBits){e.client_max_window_bits=this._options.clientMaxWindowBits}else if(this._options.clientMaxWindowBits==null){e.client_max_window_bits=true}return e}accept(e){e=this.normalizeParams(e);this.params=this._isServer?this.acceptAsServer(e):this.acceptAsClient(e);return this.params}cleanup(){if(this._inflate){this._inflate.close();this._inflate=null}if(this._deflate){const e=this._deflate[h];this._deflate.close();this._deflate=null;if(e){e(new Error("The deflate stream was closed while data was being processed"))}}}acceptAsServer(e){const t=this._options;const s=e.find((e=>{if(t.serverNoContextTakeover===false&&e.server_no_context_takeover||e.server_max_window_bits&&(t.serverMaxWindowBits===false||typeof t.serverMaxWindowBits==="number"&&t.serverMaxWindowBits>e.server_max_window_bits)||typeof t.clientMaxWindowBits==="number"&&!e.client_max_window_bits){return false}return true}));if(!s){throw new Error("None of the extension offers can be accepted")}if(t.serverNoContextTakeover){s.server_no_context_takeover=true}if(t.clientNoContextTakeover){s.client_no_context_takeover=true}if(typeof t.serverMaxWindowBits==="number"){s.server_max_window_bits=t.serverMaxWindowBits}if(typeof t.clientMaxWindowBits==="number"){s.client_max_window_bits=t.clientMaxWindowBits}else if(s.client_max_window_bits===true||t.clientMaxWindowBits===false){delete s.client_max_window_bits}return s}acceptAsClient(e){const t=e[0];if(this._options.clientNoContextTakeover===false&&t.client_no_context_takeover){throw new Error('Unexpected parameter "client_no_context_takeover"')}if(!t.client_max_window_bits){if(typeof this._options.clientMaxWindowBits==="number"){t.client_max_window_bits=this._options.clientMaxWindowBits}}else if(this._options.clientMaxWindowBits===false||typeof this._options.clientMaxWindowBits==="number"&&t.client_max_window_bits>this._options.clientMaxWindowBits){throw new Error('Unexpected or invalid parameter "client_max_window_bits"')}return t}normalizeParams(e){e.forEach((e=>{Object.keys(e).forEach((t=>{let s=e[t];if(s.length>1){throw new Error(`Parameter "${t}" must have only a single value`)}s=s[0];if(t==="client_max_window_bits"){if(s!==true){const e=+s;if(!Number.isInteger(e)||e<8||e>15){throw new TypeError(`Invalid value for parameter "${t}": ${s}`)}s=e}else if(!this._isServer){throw new TypeError(`Invalid value for parameter "${t}": ${s}`)}}else if(t==="server_max_window_bits"){const e=+s;if(!Number.isInteger(e)||e<8||e>15){throw new TypeError(`Invalid value for parameter "${t}": ${s}`)}s=e}else if(t==="client_no_context_takeover"||t==="server_no_context_takeover"){if(s!==true){throw new TypeError(`Invalid value for parameter "${t}": ${s}`)}}else{throw new Error(`Unknown parameter "${t}"`)}e[t]=s}))}));return e}decompress(e,t,s){p.add((r=>{this._decompress(e,t,((e,t)=>{r();s(e,t)}))}))}compress(e,t,s){p.add((r=>{this._compress(e,t,((e,t)=>{r();s(e,t)}))}))}_decompress(e,t,s){const o=this._isServer?"client":"server";if(!this._inflate){const e=`${o}_max_window_bits`;const t=typeof this.params[e]!=="number"?r.Z_DEFAULT_WINDOWBITS:this.params[e];this._inflate=r.createInflateRaw({...this._options.zlibInflateOptions,windowBits:t});this._inflate[l]=this;this._inflate[f]=0;this._inflate[u]=[];this._inflate.on("error",inflateOnError);this._inflate.on("data",inflateOnData)}this._inflate[h]=s;this._inflate.write(e);if(t)this._inflate.write(c);this._inflate.flush((()=>{const e=this._inflate[d];if(e){this._inflate.close();this._inflate=null;s(e);return}const r=n.concat(this._inflate[u],this._inflate[f]);if(this._inflate._readableState.endEmitted){this._inflate.close();this._inflate=null}else{this._inflate[f]=0;this._inflate[u]=[];if(t&&this.params[`${o}_no_context_takeover`]){this._inflate.reset()}}s(null,r)}))}_compress(e,t,s){const o=this._isServer?"server":"client";if(!this._deflate){const e=`${o}_max_window_bits`;const t=typeof this.params[e]!=="number"?r.Z_DEFAULT_WINDOWBITS:this.params[e];this._deflate=r.createDeflateRaw({...this._options.zlibDeflateOptions,windowBits:t});this._deflate[f]=0;this._deflate[u]=[];this._deflate.on("data",deflateOnData)}this._deflate[h]=s;this._deflate.write(e);this._deflate.flush(r.Z_SYNC_FLUSH,(()=>{if(!this._deflate){return}let e=n.concat(this._deflate[u],this._deflate[f]);if(t){e=new a(e.buffer,e.byteOffset,e.length-4)}this._deflate[h]=null;this._deflate[f]=0;this._deflate[u]=[];if(t&&this.params[`${o}_no_context_takeover`]){this._deflate.reset()}s(null,e)}))}}e.exports=PerMessageDeflate;function deflateOnData(e){this[u].push(e);this[f]+=e.length}function inflateOnData(e){this[f]+=e.length;if(this[l]._maxPayload<1||this[f]<=this[l]._maxPayload){this[u].push(e);return}this[d]=new RangeError("Max payload size exceeded");this[d].code="WS_ERR_UNSUPPORTED_MESSAGE_LENGTH";this[d][i]=1009;this.removeListener("data",inflateOnData);this.reset()}function inflateOnError(e){this[l]._inflate=null;e[i]=1007;this[h](e)}},500:(e,t,s)=>{"use strict";const{Writable:r}=s(203);const n=s(933);const{BINARY_TYPES:o,EMPTY_BUFFER:i,kStatusCode:a,kWebSocket:c}=s(112);const{concat:l,toArrayBuffer:f,unmask:h}=s(356);const{isValidStatusCode:u,isValidUTF8:d}=s(754);const p=Buffer[Symbol.species];const _=0;const m=1;const b=2;const g=3;const y=4;const S=5;const v=6;class Receiver extends r{constructor(e={}){super();this._allowSynchronousEvents=e.allowSynchronousEvents!==undefined?e.allowSynchronousEvents:true;this._binaryType=e.binaryType||o[0];this._extensions=e.extensions||{};this._isServer=!!e.isServer;this._maxPayload=e.maxPayload|0;this._skipUTF8Validation=!!e.skipUTF8Validation;this[c]=undefined;this._bufferedBytes=0;this._buffers=[];this._compressed=false;this._payloadLength=0;this._mask=undefined;this._fragmented=0;this._masked=false;this._fin=false;this._opcode=0;this._totalPayloadLength=0;this._messageLength=0;this._fragments=[];this._errored=false;this._loop=false;this._state=_}_write(e,t,s){if(this._opcode===8&&this._state==_)return s();this._bufferedBytes+=e.length;this._buffers.push(e);this.startLoop(s)}consume(e){this._bufferedBytes-=e;if(e===this._buffers[0].length)return this._buffers.shift();if(e<this._buffers[0].length){const t=this._buffers[0];this._buffers[0]=new p(t.buffer,t.byteOffset+e,t.length-e);return new p(t.buffer,t.byteOffset,e)}const t=Buffer.allocUnsafe(e);do{const s=this._buffers[0];const r=t.length-e;if(e>=s.length){t.set(this._buffers.shift(),r)}else{t.set(new Uint8Array(s.buffer,s.byteOffset,e),r);this._buffers[0]=new p(s.buffer,s.byteOffset+e,s.length-e)}e-=s.length}while(e>0);return t}startLoop(e){this._loop=true;do{switch(this._state){case _:this.getInfo(e);break;case m:this.getPayloadLength16(e);break;case b:this.getPayloadLength64(e);break;case g:this.getMask();break;case y:this.getData(e);break;case S:case v:this._loop=false;return}}while(this._loop);if(!this._errored)e()}getInfo(e){if(this._bufferedBytes<2){this._loop=false;return}const t=this.consume(2);if((t[0]&48)!==0){const t=this.createError(RangeError,"RSV2 and RSV3 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_2_3");e(t);return}const s=(t[0]&64)===64;if(s&&!this._extensions[n.extensionName]){const t=this.createError(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1");e(t);return}this._fin=(t[0]&128)===128;this._opcode=t[0]&15;this._payloadLength=t[1]&127;if(this._opcode===0){if(s){const t=this.createError(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1");e(t);return}if(!this._fragmented){const t=this.createError(RangeError,"invalid opcode 0",true,1002,"WS_ERR_INVALID_OPCODE");e(t);return}this._opcode=this._fragmented}else if(this._opcode===1||this._opcode===2){if(this._fragmented){const t=this.createError(RangeError,`invalid opcode ${this._opcode}`,true,1002,"WS_ERR_INVALID_OPCODE");e(t);return}this._compressed=s}else if(this._opcode>7&&this._opcode<11){if(!this._fin){const t=this.createError(RangeError,"FIN must be set",true,1002,"WS_ERR_EXPECTED_FIN");e(t);return}if(s){const t=this.createError(RangeError,"RSV1 must be clear",true,1002,"WS_ERR_UNEXPECTED_RSV_1");e(t);return}if(this._payloadLength>125||this._opcode===8&&this._payloadLength===1){const t=this.createError(RangeError,`invalid payload length ${this._payloadLength}`,true,1002,"WS_ERR_INVALID_CONTROL_PAYLOAD_LENGTH");e(t);return}}else{const t=this.createError(RangeError,`invalid opcode ${this._opcode}`,true,1002,"WS_ERR_INVALID_OPCODE");e(t);return}if(!this._fin&&!this._fragmented)this._fragmented=this._opcode;this._masked=(t[1]&128)===128;if(this._isServer){if(!this._masked){const t=this.createError(RangeError,"MASK must be set",true,1002,"WS_ERR_EXPECTED_MASK");e(t);return}}else if(this._masked){const t=this.createError(RangeError,"MASK must be clear",true,1002,"WS_ERR_UNEXPECTED_MASK");e(t);return}if(this._payloadLength===126)this._state=m;else if(this._payloadLength===127)this._state=b;else this.haveLength(e)}getPayloadLength16(e){if(this._bufferedBytes<2){this._loop=false;return}this._payloadLength=this.consume(2).readUInt16BE(0);this.haveLength(e)}getPayloadLength64(e){if(this._bufferedBytes<8){this._loop=false;return}const t=this.consume(8);const s=t.readUInt32BE(0);if(s>Math.pow(2,53-32)-1){const t=this.createError(RangeError,"Unsupported WebSocket frame: payload length > 2^53 - 1",false,1009,"WS_ERR_UNSUPPORTED_DATA_PAYLOAD_LENGTH");e(t);return}this._payloadLength=s*Math.pow(2,32)+t.readUInt32BE(4);this.haveLength(e)}haveLength(e){if(this._payloadLength&&this._opcode<8){this._totalPayloadLength+=this._payloadLength;if(this._totalPayloadLength>this._maxPayload&&this._maxPayload>0){const t=this.createError(RangeError,"Max payload size exceeded",false,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");e(t);return}}if(this._masked)this._state=g;else this._state=y}getMask(){if(this._bufferedBytes<4){this._loop=false;return}this._mask=this.consume(4);this._state=y}getData(e){let t=i;if(this._payloadLength){if(this._bufferedBytes<this._payloadLength){this._loop=false;return}t=this.consume(this._payloadLength);if(this._masked&&(this._mask[0]|this._mask[1]|this._mask[2]|this._mask[3])!==0){h(t,this._mask)}}if(this._opcode>7){this.controlMessage(t,e);return}if(this._compressed){this._state=S;this.decompress(t,e);return}if(t.length){this._messageLength=this._totalPayloadLength;this._fragments.push(t)}this.dataMessage(e)}decompress(e,t){const s=this._extensions[n.extensionName];s.decompress(e,this._fin,((e,s)=>{if(e)return t(e);if(s.length){this._messageLength+=s.length;if(this._messageLength>this._maxPayload&&this._maxPayload>0){const e=this.createError(RangeError,"Max payload size exceeded",false,1009,"WS_ERR_UNSUPPORTED_MESSAGE_LENGTH");t(e);return}this._fragments.push(s)}this.dataMessage(t);if(this._state===_)this.startLoop(t)}))}dataMessage(e){if(!this._fin){this._state=_;return}const t=this._messageLength;const s=this._fragments;this._totalPayloadLength=0;this._messageLength=0;this._fragmented=0;this._fragments=[];if(this._opcode===2){let r;if(this._binaryType==="nodebuffer"){r=l(s,t)}else if(this._binaryType==="arraybuffer"){r=f(l(s,t))}else if(this._binaryType==="blob"){r=new Blob(s)}else{r=s}if(this._allowSynchronousEvents){this.emit("message",r,true);this._state=_}else{this._state=v;setImmediate((()=>{this.emit("message",r,true);this._state=_;this.startLoop(e)}))}}else{const r=l(s,t);if(!this._skipUTF8Validation&&!d(r)){const t=this.createError(Error,"invalid UTF-8 sequence",true,1007,"WS_ERR_INVALID_UTF8");e(t);return}if(this._state===S||this._allowSynchronousEvents){this.emit("message",r,false);this._state=_}else{this._state=v;setImmediate((()=>{this.emit("message",r,false);this._state=_;this.startLoop(e)}))}}}controlMessage(e,t){if(this._opcode===8){if(e.length===0){this._loop=false;this.emit("conclude",1005,i);this.end()}else{const s=e.readUInt16BE(0);if(!u(s)){const e=this.createError(RangeError,`invalid status code ${s}`,true,1002,"WS_ERR_INVALID_CLOSE_CODE");t(e);return}const r=new p(e.buffer,e.byteOffset+2,e.length-2);if(!this._skipUTF8Validation&&!d(r)){const e=this.createError(Error,"invalid UTF-8 sequence",true,1007,"WS_ERR_INVALID_UTF8");t(e);return}this._loop=false;this.emit("conclude",s,r);this.end()}this._state=_;return}if(this._allowSynchronousEvents){this.emit(this._opcode===9?"ping":"pong",e);this._state=_}else{this._state=v;setImmediate((()=>{this.emit(this._opcode===9?"ping":"pong",e);this._state=_;this.startLoop(t)}))}}createError(e,t,s,r,n){this._loop=false;this._errored=true;const o=new e(s?`Invalid WebSocket frame: ${t}`:t);Error.captureStackTrace(o,this.createError);o.code=n;o[a]=r;return o}}e.exports=Receiver},124:(e,t,s)=>{"use strict";const{Duplex:r}=s(203);const{randomFillSync:n}=s(982);const o=s(933);const{EMPTY_BUFFER:i,kWebSocket:a,NOOP:c}=s(112);const{isBlob:l,isValidStatusCode:f}=s(754);const{mask:h,toBuffer:u}=s(356);const d=Symbol("kByteLength");const p=Buffer.alloc(4);const _=8*1024;let m;let b=_;const g=0;const y=1;const S=2;class Sender{constructor(e,t,s){this._extensions=t||{};if(s){this._generateMask=s;this._maskBuffer=Buffer.alloc(4)}this._socket=e;this._firstFragment=true;this._compress=false;this._bufferedBytes=0;this._queue=[];this._state=g;this.onerror=c;this[a]=undefined}static frame(e,t){let s;let r=false;let o=2;let i=false;if(t.mask){s=t.maskBuffer||p;if(t.generateMask){t.generateMask(s)}else{if(b===_){if(m===undefined){m=Buffer.alloc(_)}n(m,0,_);b=0}s[0]=m[b++];s[1]=m[b++];s[2]=m[b++];s[3]=m[b++]}i=(s[0]|s[1]|s[2]|s[3])===0;o=6}let a;if(typeof e==="string"){if((!t.mask||i)&&t[d]!==undefined){a=t[d]}else{e=Buffer.from(e);a=e.length}}else{a=e.length;r=t.mask&&t.readOnly&&!i}let c=a;if(a>=65536){o+=8;c=127}else if(a>125){o+=2;c=126}const l=Buffer.allocUnsafe(r?a+o:o);l[0]=t.fin?t.opcode|128:t.opcode;if(t.rsv1)l[0]|=64;l[1]=c;if(c===126){l.writeUInt16BE(a,2)}else if(c===127){l[2]=l[3]=0;l.writeUIntBE(a,4,6)}if(!t.mask)return[l,e];l[1]|=128;l[o-4]=s[0];l[o-3]=s[1];l[o-2]=s[2];l[o-1]=s[3];if(i)return[l,e];if(r){h(e,s,l,o,a);return[l]}h(e,s,e,0,a);return[l,e]}close(e,t,s,r){let n;if(e===undefined){n=i}else if(typeof e!=="number"||!f(e)){throw new TypeError("First argument must be a valid error code number")}else if(t===undefined||!t.length){n=Buffer.allocUnsafe(2);n.writeUInt16BE(e,0)}else{const s=Buffer.byteLength(t);if(s>123){throw new RangeError("The message must not be greater than 123 bytes")}n=Buffer.allocUnsafe(2+s);n.writeUInt16BE(e,0);if(typeof t==="string"){n.write(t,2)}else{n.set(t,2)}}const o={[d]:n.length,fin:true,generateMask:this._generateMask,mask:s,maskBuffer:this._maskBuffer,opcode:8,readOnly:false,rsv1:false};if(this._state!==g){this.enqueue([this.dispatch,n,false,o,r])}else{this.sendFrame(Sender.frame(n,o),r)}}ping(e,t,s){let r;let n;if(typeof e==="string"){r=Buffer.byteLength(e);n=false}else if(l(e)){r=e.size;n=false}else{e=u(e);r=e.length;n=u.readOnly}if(r>125){throw new RangeError("The data size must not be greater than 125 bytes")}const o={[d]:r,fin:true,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:9,readOnly:n,rsv1:false};if(l(e)){if(this._state!==g){this.enqueue([this.getBlobData,e,false,o,s])}else{this.getBlobData(e,false,o,s)}}else if(this._state!==g){this.enqueue([this.dispatch,e,false,o,s])}else{this.sendFrame(Sender.frame(e,o),s)}}pong(e,t,s){let r;let n;if(typeof e==="string"){r=Buffer.byteLength(e);n=false}else if(l(e)){r=e.size;n=false}else{e=u(e);r=e.length;n=u.readOnly}if(r>125){throw new RangeError("The data size must not be greater than 125 bytes")}const o={[d]:r,fin:true,generateMask:this._generateMask,mask:t,maskBuffer:this._maskBuffer,opcode:10,readOnly:n,rsv1:false};if(l(e)){if(this._state!==g){this.enqueue([this.getBlobData,e,false,o,s])}else{this.getBlobData(e,false,o,s)}}else if(this._state!==g){this.enqueue([this.dispatch,e,false,o,s])}else{this.sendFrame(Sender.frame(e,o),s)}}send(e,t,s){const r=this._extensions[o.extensionName];let n=t.binary?2:1;let i=t.compress;let a;let c;if(typeof e==="string"){a=Buffer.byteLength(e);c=false}else if(l(e)){a=e.size;c=false}else{e=u(e);a=e.length;c=u.readOnly}if(this._firstFragment){this._firstFragment=false;if(i&&r&&r.params[r._isServer?"server_no_context_takeover":"client_no_context_takeover"]){i=a>=r._threshold}this._compress=i}else{i=false;n=0}if(t.fin)this._firstFragment=true;const f={[d]:a,fin:t.fin,generateMask:this._generateMask,mask:t.mask,maskBuffer:this._maskBuffer,opcode:n,readOnly:c,rsv1:i};if(l(e)){if(this._state!==g){this.enqueue([this.getBlobData,e,this._compress,f,s])}else{this.getBlobData(e,this._compress,f,s)}}else if(this._state!==g){this.enqueue([this.dispatch,e,this._compress,f,s])}else{this.dispatch(e,this._compress,f,s)}}getBlobData(e,t,s,r){this._bufferedBytes+=s[d];this._state=S;e.arrayBuffer().then((e=>{if(this._socket.destroyed){const e=new Error("The socket was closed while the blob was being read");process.nextTick(callCallbacks,this,e,r);return}this._bufferedBytes-=s[d];const n=u(e);if(!t){this._state=g;this.sendFrame(Sender.frame(n,s),r);this.dequeue()}else{this.dispatch(n,t,s,r)}})).catch((e=>{process.nextTick(onError,this,e,r)}))}dispatch(e,t,s,r){if(!t){this.sendFrame(Sender.frame(e,s),r);return}const n=this._extensions[o.extensionName];this._bufferedBytes+=s[d];this._state=y;n.compress(e,s.fin,((e,t)=>{if(this._socket.destroyed){const e=new Error("The socket was closed while data was being compressed");callCallbacks(this,e,r);return}this._bufferedBytes-=s[d];this._state=g;s.readOnly=false;this.sendFrame(Sender.frame(t,s),r);this.dequeue()}))}dequeue(){while(this._state===g&&this._queue.length){const e=this._queue.shift();this._bufferedBytes-=e[3][d];Reflect.apply(e[0],this,e.slice(1))}}enqueue(e){this._bufferedBytes+=e[3][d];this._queue.push(e)}sendFrame(e,t){if(e.length===2){this._socket.cork();this._socket.write(e[0]);this._socket.write(e[1],t);this._socket.uncork()}else{this._socket.write(e[0],t)}}}e.exports=Sender;function callCallbacks(e,t,s){if(typeof s==="function")s(t);for(let s=0;s<e._queue.length;s++){const r=e._queue[s];const n=r[r.length-1];if(typeof n==="function")n(t)}}function onError(e,t,s){callCallbacks(e,t,s);e.onerror(t)}},597:(e,t,s)=>{"use strict";const{Duplex:r}=s(203);function emitClose(e){e.emit("close")}function duplexOnEnd(){if(!this.destroyed&&this._writableState.finished){this.destroy()}}function duplexOnError(e){this.removeListener("error",duplexOnError);this.destroy();if(this.listenerCount("error")===0){this.emit("error",e)}}function createWebSocketStream(e,t){let s=true;const n=new r({...t,autoDestroy:false,emitClose:false,objectMode:false,writableObjectMode:false});e.on("message",(function message(t,s){const r=!s&&n._readableState.objectMode?t.toString():t;if(!n.push(r))e.pause()}));e.once("error",(function error(e){if(n.destroyed)return;s=false;n.destroy(e)}));e.once("close",(function close(){if(n.destroyed)return;n.push(null)}));n._destroy=function(t,r){if(e.readyState===e.CLOSED){r(t);process.nextTick(emitClose,n);return}let o=false;e.once("error",(function error(e){o=true;r(e)}));e.once("close",(function close(){if(!o)r(t);process.nextTick(emitClose,n)}));if(s)e.terminate()};n._final=function(t){if(e.readyState===e.CONNECTING){e.once("open",(function open(){n._final(t)}));return}if(e._socket===null)return;if(e._socket._writableState.finished){t();if(n._readableState.endEmitted)n.destroy()}else{e._socket.once("finish",(function finish(){t()}));e.close()}};n._read=function(){if(e.isPaused)e.resume()};n._write=function(t,s,r){if(e.readyState===e.CONNECTING){e.once("open",(function open(){n._write(t,s,r)}));return}e.send(t,r)};n.on("end",duplexOnEnd);n.on("error",duplexOnError);return n}e.exports=createWebSocketStream},443:(e,t,s)=>{"use strict";const{tokenChars:r}=s(754);function parse(e){const t=new Set;let s=-1;let n=-1;let o=0;for(o;o<e.length;o++){const i=e.charCodeAt(o);if(n===-1&&r[i]===1){if(s===-1)s=o}else if(o!==0&&(i===32||i===9)){if(n===-1&&s!==-1)n=o}else if(i===44){if(s===-1){throw new SyntaxError(`Unexpected character at index ${o}`)}if(n===-1)n=o;const r=e.slice(s,n);if(t.has(r)){throw new SyntaxError(`The "${r}" subprotocol is duplicated`)}t.add(r);s=n=-1}else{throw new SyntaxError(`Unexpected character at index ${o}`)}}if(s===-1||n!==-1){throw new SyntaxError("Unexpected end of input")}const i=e.slice(s,o);if(t.has(i)){throw new SyntaxError(`The "${i}" subprotocol is duplicated`)}t.add(i);return t}e.exports={parse:parse}},754:(e,t,s)=>{"use strict";const{isUtf8:r}=s(181);const{hasBlob:n}=s(112);const o=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,0];function isValidStatusCode(e){return e>=1e3&&e<=1014&&e!==1004&&e!==1005&&e!==1006||e>=3e3&&e<=4999}function _isValidUTF8(e){const t=e.length;let s=0;while(s<t){if((e[s]&128)===0){s++}else if((e[s]&224)===192){if(s+1===t||(e[s+1]&192)!==128||(e[s]&254)===192){return false}s+=2}else if((e[s]&240)===224){if(s+2>=t||(e[s+1]&192)!==128||(e[s+2]&192)!==128||e[s]===224&&(e[s+1]&224)===128||e[s]===237&&(e[s+1]&224)===160){return false}s+=3}else if((e[s]&248)===240){if(s+3>=t||(e[s+1]&192)!==128||(e[s+2]&192)!==128||(e[s+3]&192)!==128||e[s]===240&&(e[s+1]&240)===128||e[s]===244&&e[s+1]>143||e[s]>244){return false}s+=4}else{return false}}return true}function isBlob(e){return n&&typeof e==="object"&&typeof e.arrayBuffer==="function"&&typeof e.type==="string"&&typeof e.stream==="function"&&(e[Symbol.toStringTag]==="Blob"||e[Symbol.toStringTag]==="File")}e.exports={isBlob:isBlob,isValidStatusCode:isValidStatusCode,isValidUTF8:_isValidUTF8,tokenChars:o};if(r){e.exports.isValidUTF8=function(e){return e.length<24?_isValidUTF8(e):r(e)}}else if(!process.env.WS_NO_UTF_8_VALIDATE){try{const t=s(988);e.exports.isValidUTF8=function(e){return e.length<32?_isValidUTF8(e):t(e)}}catch(e){}}},672:(e,t,s)=>{"use strict";const r=s(434);const n=s(611);const{Duplex:o}=s(203);const{createHash:i}=s(982);const a=s(731);const c=s(933);const l=s(443);const f=s(102);const{GUID:h,kWebSocket:u}=s(112);const d=/^[+/0-9A-Za-z]{22}==$/;const p=0;const _=1;const m=2;class WebSocketServer extends r{constructor(e,t){super();e={allowSynchronousEvents:true,autoPong:true,maxPayload:100*1024*1024,skipUTF8Validation:false,perMessageDeflate:false,handleProtocols:null,clientTracking:true,verifyClient:null,noServer:false,backlog:null,server:null,host:null,path:null,port:null,WebSocket:f,...e};if(e.port==null&&!e.server&&!e.noServer||e.port!=null&&(e.server||e.noServer)||e.server&&e.noServer){throw new TypeError('One and only one of the "port", "server", or "noServer" options '+"must be specified")}if(e.port!=null){this._server=n.createServer(((e,t)=>{const s=n.STATUS_CODES[426];t.writeHead(426,{"Content-Length":s.length,"Content-Type":"text/plain"});t.end(s)}));this._server.listen(e.port,e.host,e.backlog,t)}else if(e.server){this._server=e.server}if(this._server){const e=this.emit.bind(this,"connection");this._removeListeners=addListeners(this._server,{listening:this.emit.bind(this,"listening"),error:this.emit.bind(this,"error"),upgrade:(t,s,r)=>{this.handleUpgrade(t,s,r,e)}})}if(e.perMessageDeflate===true)e.perMessageDeflate={};if(e.clientTracking){this.clients=new Set;this._shouldEmitClose=false}this.options=e;this._state=p}address(){if(this.options.noServer){throw new Error('The server is operating in "noServer" mode')}if(!this._server)return null;return this._server.address()}close(e){if(this._state===m){if(e){this.once("close",(()=>{e(new Error("The server is not running"))}))}process.nextTick(emitClose,this);return}if(e)this.once("close",e);if(this._state===_)return;this._state=_;if(this.options.noServer||this.options.server){if(this._server){this._removeListeners();this._removeListeners=this._server=null}if(this.clients){if(!this.clients.size){process.nextTick(emitClose,this)}else{this._shouldEmitClose=true}}else{process.nextTick(emitClose,this)}}else{const e=this._server;this._removeListeners();this._removeListeners=this._server=null;e.close((()=>{emitClose(this)}))}}shouldHandle(e){if(this.options.path){const t=e.url.indexOf("?");const s=t!==-1?e.url.slice(0,t):e.url;if(s!==this.options.path)return false}return true}handleUpgrade(e,t,s,r){t.on("error",socketOnError);const n=e.headers["sec-websocket-key"];const o=e.headers.upgrade;const i=+e.headers["sec-websocket-version"];if(e.method!=="GET"){const s="Invalid HTTP method";abortHandshakeOrEmitwsClientError(this,e,t,405,s);return}if(o===undefined||o.toLowerCase()!=="websocket"){const s="Invalid Upgrade header";abortHandshakeOrEmitwsClientError(this,e,t,400,s);return}if(n===undefined||!d.test(n)){const s="Missing or invalid Sec-WebSocket-Key header";abortHandshakeOrEmitwsClientError(this,e,t,400,s);return}if(i!==8&&i!==13){const s="Missing or invalid Sec-WebSocket-Version header";abortHandshakeOrEmitwsClientError(this,e,t,400,s);return}if(!this.shouldHandle(e)){abortHandshake(t,400);return}const f=e.headers["sec-websocket-protocol"];let h=new Set;if(f!==undefined){try{h=l.parse(f)}catch(s){const r="Invalid Sec-WebSocket-Protocol header";abortHandshakeOrEmitwsClientError(this,e,t,400,r);return}}const u=e.headers["sec-websocket-extensions"];const p={};if(this.options.perMessageDeflate&&u!==undefined){const s=new c(this.options.perMessageDeflate,true,this.options.maxPayload);try{const e=a.parse(u);if(e[c.extensionName]){s.accept(e[c.extensionName]);p[c.extensionName]=s}}catch(s){const r="Invalid or unacceptable Sec-WebSocket-Extensions header";abortHandshakeOrEmitwsClientError(this,e,t,400,r);return}}if(this.options.verifyClient){const o={origin:e.headers[`${i===8?"sec-websocket-origin":"origin"}`],secure:!!(e.socket.authorized||e.socket.encrypted),req:e};if(this.options.verifyClient.length===2){this.options.verifyClient(o,((o,i,a,c)=>{if(!o){return abortHandshake(t,i||401,a,c)}this.completeUpgrade(p,n,h,e,t,s,r)}));return}if(!this.options.verifyClient(o))return abortHandshake(t,401)}this.completeUpgrade(p,n,h,e,t,s,r)}completeUpgrade(e,t,s,r,n,o,l){if(!n.readable||!n.writable)return n.destroy();if(n[u]){throw new Error("server.handleUpgrade() was called more than once with the same "+"socket, possibly due to a misconfiguration")}if(this._state>p)return abortHandshake(n,503);const f=i("sha1").update(t+h).digest("base64");const d=["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade",`Sec-WebSocket-Accept: ${f}`];const _=new this.options.WebSocket(null,undefined,this.options);if(s.size){const e=this.options.handleProtocols?this.options.handleProtocols(s,r):s.values().next().value;if(e){d.push(`Sec-WebSocket-Protocol: ${e}`);_._protocol=e}}if(e[c.extensionName]){const t=e[c.extensionName].params;const s=a.format({[c.extensionName]:[t]});d.push(`Sec-WebSocket-Extensions: ${s}`);_._extensions=e}this.emit("headers",d,r);n.write(d.concat("\r\n").join("\r\n"));n.removeListener("error",socketOnError);_.setSocket(n,o,{allowSynchronousEvents:this.options.allowSynchronousEvents,maxPayload:this.options.maxPayload,skipUTF8Validation:this.options.skipUTF8Validation});if(this.clients){this.clients.add(_);_.on("close",(()=>{this.clients.delete(_);if(this._shouldEmitClose&&!this.clients.size){process.nextTick(emitClose,this)}}))}l(_,r)}}e.exports=WebSocketServer;function addListeners(e,t){for(const s of Object.keys(t))e.on(s,t[s]);return function removeListeners(){for(const s of Object.keys(t)){e.removeListener(s,t[s])}}}function emitClose(e){e._state=m;e.emit("close")}function socketOnError(){this.destroy()}function abortHandshake(e,t,s,r){s=s||n.STATUS_CODES[t];r={Connection:"close","Content-Type":"text/html","Content-Length":Buffer.byteLength(s),...r};e.once("finish",e.destroy);e.end(`HTTP/1.1 ${t} ${n.STATUS_CODES[t]}\r\n`+Object.keys(r).map((e=>`${e}: ${r[e]}`)).join("\r\n")+"\r\n\r\n"+s)}function abortHandshakeOrEmitwsClientError(e,t,s,r,n){if(e.listenerCount("wsClientError")){const r=new Error(n);Error.captureStackTrace(r,abortHandshakeOrEmitwsClientError);e.emit("wsClientError",r,s,t)}else{abortHandshake(s,r,n)}}},102:(e,t,s)=>{"use strict";const r=s(434);const n=s(692);const o=s(611);const i=s(278);const a=s(756);const{randomBytes:c,createHash:l}=s(982);const{Duplex:f,Readable:h}=s(203);const{URL:u}=s(16);const d=s(933);const p=s(500);const _=s(124);const{isBlob:m}=s(754);const{BINARY_TYPES:b,EMPTY_BUFFER:g,GUID:y,kForOnEventAttribute:S,kListener:v,kStatusCode:k,kWebSocket:w,NOOP:E}=s(112);const{EventTarget:{addEventListener:x,removeEventListener:C}}=s(139);const{format:O,parse:T}=s(731);const{toBuffer:N}=s(356);const L=30*1e3;const W=Symbol("kAborted");const P=[8,13];const U=["CONNECTING","OPEN","CLOSING","CLOSED"];const B=/^[!#$%&'*+\-.0-9A-Z^_`|a-z~]+$/;class WebSocket extends r{constructor(e,t,s){super();this._binaryType=b[0];this._closeCode=1006;this._closeFrameReceived=false;this._closeFrameSent=false;this._closeMessage=g;this._closeTimer=null;this._errorEmitted=false;this._extensions={};this._paused=false;this._protocol="";this._readyState=WebSocket.CONNECTING;this._receiver=null;this._sender=null;this._socket=null;if(e!==null){this._bufferedAmount=0;this._isServer=false;this._redirects=0;if(t===undefined){t=[]}else if(!Array.isArray(t)){if(typeof t==="object"&&t!==null){s=t;t=[]}else{t=[t]}}initAsClient(this,e,t,s)}else{this._autoPong=s.autoPong;this._isServer=true}}get binaryType(){return this._binaryType}set binaryType(e){if(!b.includes(e))return;this._binaryType=e;if(this._receiver)this._receiver._binaryType=e}get bufferedAmount(){if(!this._socket)return this._bufferedAmount;return this._socket._writableState.length+this._sender._bufferedBytes}get extensions(){return Object.keys(this._extensions).join()}get isPaused(){return this._paused}get onclose(){return null}get onerror(){return null}get onopen(){return null}get onmessage(){return null}get protocol(){return this._protocol}get readyState(){return this._readyState}get url(){return this._url}setSocket(e,t,s){const r=new p({allowSynchronousEvents:s.allowSynchronousEvents,binaryType:this.binaryType,extensions:this._extensions,isServer:this._isServer,maxPayload:s.maxPayload,skipUTF8Validation:s.skipUTF8Validation});const n=new _(e,this._extensions,s.generateMask);this._receiver=r;this._sender=n;this._socket=e;r[w]=this;n[w]=this;e[w]=this;r.on("conclude",receiverOnConclude);r.on("drain",receiverOnDrain);r.on("error",receiverOnError);r.on("message",receiverOnMessage);r.on("ping",receiverOnPing);r.on("pong",receiverOnPong);n.onerror=senderOnError;if(e.setTimeout)e.setTimeout(0);if(e.setNoDelay)e.setNoDelay();if(t.length>0)e.unshift(t);e.on("close",socketOnClose);e.on("data",socketOnData);e.on("end",socketOnEnd);e.on("error",socketOnError);this._readyState=WebSocket.OPEN;this.emit("open")}emitClose(){if(!this._socket){this._readyState=WebSocket.CLOSED;this.emit("close",this._closeCode,this._closeMessage);return}if(this._extensions[d.extensionName]){this._extensions[d.extensionName].cleanup()}this._receiver.removeAllListeners();this._readyState=WebSocket.CLOSED;this.emit("close",this._closeCode,this._closeMessage)}close(e,t){if(this.readyState===WebSocket.CLOSED)return;if(this.readyState===WebSocket.CONNECTING){const e="WebSocket was closed before the connection was established";abortHandshake(this,this._req,e);return}if(this.readyState===WebSocket.CLOSING){if(this._closeFrameSent&&(this._closeFrameReceived||this._receiver._writableState.errorEmitted)){this._socket.end()}return}this._readyState=WebSocket.CLOSING;this._sender.close(e,t,!this._isServer,(e=>{if(e)return;this._closeFrameSent=true;if(this._closeFrameReceived||this._receiver._writableState.errorEmitted){this._socket.end()}}));setCloseTimer(this)}pause(){if(this.readyState===WebSocket.CONNECTING||this.readyState===WebSocket.CLOSED){return}this._paused=true;this._socket.pause()}ping(e,t,s){if(this.readyState===WebSocket.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof e==="function"){s=e;e=t=undefined}else if(typeof t==="function"){s=t;t=undefined}if(typeof e==="number")e=e.toString();if(this.readyState!==WebSocket.OPEN){sendAfterClose(this,e,s);return}if(t===undefined)t=!this._isServer;this._sender.ping(e||g,t,s)}pong(e,t,s){if(this.readyState===WebSocket.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof e==="function"){s=e;e=t=undefined}else if(typeof t==="function"){s=t;t=undefined}if(typeof e==="number")e=e.toString();if(this.readyState!==WebSocket.OPEN){sendAfterClose(this,e,s);return}if(t===undefined)t=!this._isServer;this._sender.pong(e||g,t,s)}resume(){if(this.readyState===WebSocket.CONNECTING||this.readyState===WebSocket.CLOSED){return}this._paused=false;if(!this._receiver._writableState.needDrain)this._socket.resume()}send(e,t,s){if(this.readyState===WebSocket.CONNECTING){throw new Error("WebSocket is not open: readyState 0 (CONNECTING)")}if(typeof t==="function"){s=t;t={}}if(typeof e==="number")e=e.toString();if(this.readyState!==WebSocket.OPEN){sendAfterClose(this,e,s);return}const r={binary:typeof e!=="string",mask:!this._isServer,compress:true,fin:true,...t};if(!this._extensions[d.extensionName]){r.compress=false}this._sender.send(e||g,r,s)}terminate(){if(this.readyState===WebSocket.CLOSED)return;if(this.readyState===WebSocket.CONNECTING){const e="WebSocket was closed before the connection was established";abortHandshake(this,this._req,e);return}if(this._socket){this._readyState=WebSocket.CLOSING;this._socket.destroy()}}}Object.defineProperty(WebSocket,"CONNECTING",{enumerable:true,value:U.indexOf("CONNECTING")});Object.defineProperty(WebSocket.prototype,"CONNECTING",{enumerable:true,value:U.indexOf("CONNECTING")});Object.defineProperty(WebSocket,"OPEN",{enumerable:true,value:U.indexOf("OPEN")});Object.defineProperty(WebSocket.prototype,"OPEN",{enumerable:true,value:U.indexOf("OPEN")});Object.defineProperty(WebSocket,"CLOSING",{enumerable:true,value:U.indexOf("CLOSING")});Object.defineProperty(WebSocket.prototype,"CLOSING",{enumerable:true,value:U.indexOf("CLOSING")});Object.defineProperty(WebSocket,"CLOSED",{enumerable:true,value:U.indexOf("CLOSED")});Object.defineProperty(WebSocket.prototype,"CLOSED",{enumerable:true,value:U.indexOf("CLOSED")});["binaryType","bufferedAmount","extensions","isPaused","protocol","readyState","url"].forEach((e=>{Object.defineProperty(WebSocket.prototype,e,{enumerable:true})}));["open","error","close","message"].forEach((e=>{Object.defineProperty(WebSocket.prototype,`on${e}`,{enumerable:true,get(){for(const t of this.listeners(e)){if(t[S])return t[v]}return null},set(t){for(const t of this.listeners(e)){if(t[S]){this.removeListener(e,t);break}}if(typeof t!=="function")return;this.addEventListener(e,t,{[S]:true})}})}));WebSocket.prototype.addEventListener=x;WebSocket.prototype.removeEventListener=C;e.exports=WebSocket;function initAsClient(e,t,s,r){const i={allowSynchronousEvents:true,autoPong:true,protocolVersion:P[1],maxPayload:100*1024*1024,skipUTF8Validation:false,perMessageDeflate:true,followRedirects:false,maxRedirects:10,...r,socketPath:undefined,hostname:undefined,protocol:undefined,timeout:undefined,method:"GET",host:undefined,path:undefined,port:undefined};e._autoPong=i.autoPong;if(!P.includes(i.protocolVersion)){throw new RangeError(`Unsupported protocol version: ${i.protocolVersion} `+`(supported versions: ${P.join(", ")})`)}let a;if(t instanceof u){a=t}else{try{a=new u(t)}catch(e){throw new SyntaxError(`Invalid URL: ${t}`)}}if(a.protocol==="http:"){a.protocol="ws:"}else if(a.protocol==="https:"){a.protocol="wss:"}e._url=a.href;const f=a.protocol==="wss:";const h=a.protocol==="ws+unix:";let p;if(a.protocol!=="ws:"&&!f&&!h){p='The URL\'s protocol must be one of "ws:", "wss:", '+'"http:", "https", or "ws+unix:"'}else if(h&&!a.pathname){p="The URL's pathname is empty"}else if(a.hash){p="The URL contains a fragment identifier"}if(p){const t=new SyntaxError(p);if(e._redirects===0){throw t}else{emitErrorAndClose(e,t);return}}const _=f?443:80;const m=c(16).toString("base64");const b=f?n.request:o.request;const g=new Set;let S;i.createConnection=i.createConnection||(f?tlsConnect:netConnect);i.defaultPort=i.defaultPort||_;i.port=a.port||_;i.host=a.hostname.startsWith("[")?a.hostname.slice(1,-1):a.hostname;i.headers={...i.headers,"Sec-WebSocket-Version":i.protocolVersion,"Sec-WebSocket-Key":m,Connection:"Upgrade",Upgrade:"websocket"};i.path=a.pathname+a.search;i.timeout=i.handshakeTimeout;if(i.perMessageDeflate){S=new d(i.perMessageDeflate!==true?i.perMessageDeflate:{},false,i.maxPayload);i.headers["Sec-WebSocket-Extensions"]=O({[d.extensionName]:S.offer()})}if(s.length){for(const e of s){if(typeof e!=="string"||!B.test(e)||g.has(e)){throw new SyntaxError("An invalid or duplicated subprotocol was specified")}g.add(e)}i.headers["Sec-WebSocket-Protocol"]=s.join(",")}if(i.origin){if(i.protocolVersion<13){i.headers["Sec-WebSocket-Origin"]=i.origin}else{i.headers.Origin=i.origin}}if(a.username||a.password){i.auth=`${a.username}:${a.password}`}if(h){const e=i.path.split(":");i.socketPath=e[0];i.path=e[1]}let v;if(i.followRedirects){if(e._redirects===0){e._originalIpc=h;e._originalSecure=f;e._originalHostOrSocketPath=h?i.socketPath:a.host;const t=r&&r.headers;r={...r,headers:{}};if(t){for(const[e,s]of Object.entries(t)){r.headers[e.toLowerCase()]=s}}}else if(e.listenerCount("redirect")===0){const t=h?e._originalIpc?i.socketPath===e._originalHostOrSocketPath:false:e._originalIpc?false:a.host===e._originalHostOrSocketPath;if(!t||e._originalSecure&&!f){delete i.headers.authorization;delete i.headers.cookie;if(!t)delete i.headers.host;i.auth=undefined}}if(i.auth&&!r.headers.authorization){r.headers.authorization="Basic "+Buffer.from(i.auth).toString("base64")}v=e._req=b(i);if(e._redirects){e.emit("redirect",e.url,v)}}else{v=e._req=b(i)}if(i.timeout){v.on("timeout",(()=>{abortHandshake(e,v,"Opening handshake has timed out")}))}v.on("error",(t=>{if(v===null||v[W])return;v=e._req=null;emitErrorAndClose(e,t)}));v.on("response",(n=>{const o=n.headers.location;const a=n.statusCode;if(o&&i.followRedirects&&a>=300&&a<400){if(++e._redirects>i.maxRedirects){abortHandshake(e,v,"Maximum redirects exceeded");return}v.abort();let n;try{n=new u(o,t)}catch(t){const s=new SyntaxError(`Invalid URL: ${o}`);emitErrorAndClose(e,s);return}initAsClient(e,n,s,r)}else if(!e.emit("unexpected-response",v,n)){abortHandshake(e,v,`Unexpected server response: ${n.statusCode}`)}}));v.on("upgrade",((t,s,r)=>{e.emit("upgrade",t);if(e.readyState!==WebSocket.CONNECTING)return;v=e._req=null;const n=t.headers.upgrade;if(n===undefined||n.toLowerCase()!=="websocket"){abortHandshake(e,s,"Invalid Upgrade header");return}const o=l("sha1").update(m+y).digest("base64");if(t.headers["sec-websocket-accept"]!==o){abortHandshake(e,s,"Invalid Sec-WebSocket-Accept header");return}const a=t.headers["sec-websocket-protocol"];let c;if(a!==undefined){if(!g.size){c="Server sent a subprotocol but none was requested"}else if(!g.has(a)){c="Server sent an invalid subprotocol"}}else if(g.size){c="Server sent no subprotocol"}if(c){abortHandshake(e,s,c);return}if(a)e._protocol=a;const f=t.headers["sec-websocket-extensions"];if(f!==undefined){if(!S){const t="Server sent a Sec-WebSocket-Extensions header but no extension "+"was requested";abortHandshake(e,s,t);return}let t;try{t=T(f)}catch(t){const r="Invalid Sec-WebSocket-Extensions header";abortHandshake(e,s,r);return}const r=Object.keys(t);if(r.length!==1||r[0]!==d.extensionName){const t="Server indicated an extension that was not requested";abortHandshake(e,s,t);return}try{S.accept(t[d.extensionName])}catch(t){const r="Invalid Sec-WebSocket-Extensions header";abortHandshake(e,s,r);return}e._extensions[d.extensionName]=S}e.setSocket(s,r,{allowSynchronousEvents:i.allowSynchronousEvents,generateMask:i.generateMask,maxPayload:i.maxPayload,skipUTF8Validation:i.skipUTF8Validation})}));if(i.finishRequest){i.finishRequest(v,e)}else{v.end()}}function emitErrorAndClose(e,t){e._readyState=WebSocket.CLOSING;e._errorEmitted=true;e.emit("error",t);e.emitClose()}function netConnect(e){e.path=e.socketPath;return i.connect(e)}function tlsConnect(e){e.path=undefined;if(!e.servername&&e.servername!==""){e.servername=i.isIP(e.host)?"":e.host}return a.connect(e)}function abortHandshake(e,t,s){e._readyState=WebSocket.CLOSING;const r=new Error(s);Error.captureStackTrace(r,abortHandshake);if(t.setHeader){t[W]=true;t.abort();if(t.socket&&!t.socket.destroyed){t.socket.destroy()}process.nextTick(emitErrorAndClose,e,r)}else{t.destroy(r);t.once("error",e.emit.bind(e,"error"));t.once("close",e.emitClose.bind(e))}}function sendAfterClose(e,t,s){if(t){const s=m(t)?t.size:N(t).length;if(e._socket)e._sender._bufferedBytes+=s;else e._bufferedAmount+=s}if(s){const t=new Error(`WebSocket is not open: readyState ${e.readyState} `+`(${U[e.readyState]})`);process.nextTick(s,t)}}function receiverOnConclude(e,t){const s=this[w];s._closeFrameReceived=true;s._closeMessage=t;s._closeCode=e;if(s._socket[w]===undefined)return;s._socket.removeListener("data",socketOnData);process.nextTick(resume,s._socket);if(e===1005)s.close();else s.close(e,t)}function receiverOnDrain(){const e=this[w];if(!e.isPaused)e._socket.resume()}function receiverOnError(e){const t=this[w];if(t._socket[w]!==undefined){t._socket.removeListener("data",socketOnData);process.nextTick(resume,t._socket);t.close(e[k])}if(!t._errorEmitted){t._errorEmitted=true;t.emit("error",e)}}function receiverOnFinish(){this[w].emitClose()}function receiverOnMessage(e,t){this[w].emit("message",e,t)}function receiverOnPing(e){const t=this[w];if(t._autoPong)t.pong(e,!this._isServer,E);t.emit("ping",e)}function receiverOnPong(e){this[w].emit("pong",e)}function resume(e){e.resume()}function senderOnError(e){const t=this[w];if(t.readyState===WebSocket.CLOSED)return;if(t.readyState===WebSocket.OPEN){t._readyState=WebSocket.CLOSING;setCloseTimer(t)}this._socket.end();if(!t._errorEmitted){t._errorEmitted=true;t.emit("error",e)}}function setCloseTimer(e){e._closeTimer=setTimeout(e._socket.destroy.bind(e._socket),L)}function socketOnClose(){const e=this[w];this.removeListener("close",socketOnClose);this.removeListener("data",socketOnData);this.removeListener("end",socketOnEnd);e._readyState=WebSocket.CLOSING;let t;if(!this._readableState.endEmitted&&!e._closeFrameReceived&&!e._receiver._writableState.errorEmitted&&(t=e._socket.read())!==null){e._receiver.write(t)}e._receiver.end();this[w]=undefined;clearTimeout(e._closeTimer);if(e._receiver._writableState.finished||e._receiver._writableState.errorEmitted){e.emitClose()}else{e._receiver.on("error",receiverOnFinish);e._receiver.on("finish",receiverOnFinish)}}function socketOnData(e){if(!this[w]._receiver.write(e)){this.pause()}}function socketOnEnd(){const e=this[w];e._readyState=WebSocket.CLOSING;e._receiver.end();this.end()}function socketOnError(){const e=this[w];this.removeListener("error",socketOnError);this.on("error",E);if(e){e._readyState=WebSocket.CLOSING;this.destroy()}}},941:module=>{module.exports=eval("require")("bufferutil")},988:module=>{module.exports=eval("require")("utf-8-validate")},181:e=>{"use strict";e.exports=require("buffer")},982:e=>{"use strict";e.exports=require("crypto")},434:e=>{"use strict";e.exports=require("events")},896:e=>{"use strict";e.exports=require("fs")},611:e=>{"use strict";e.exports=require("http")},692:e=>{"use strict";e.exports=require("https")},278:e=>{"use strict";e.exports=require("net")},857:e=>{"use strict";e.exports=require("os")},928:e=>{"use strict";e.exports=require("path")},203:e=>{"use strict";e.exports=require("stream")},756:e=>{"use strict";e.exports=require("tls")},16:e=>{"use strict";e.exports=require("url")},106:e=>{"use strict";e.exports=require("zlib")}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var s=__webpack_module_cache__[e]={exports:{}};var r=true;try{__webpack_modules__[e].call(s.exports,s,s.exports,__nccwpck_require__);r=false}finally{if(r)delete __webpack_module_cache__[e]}return s.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(642);module.exports=__webpack_exports__})();
|