xshell 1.0.197 → 1.0.199
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/net.browser.d.ts +9 -4
- package/net.browser.js +35 -28
- package/net.d.ts +9 -4
- package/net.js +36 -29
- package/package.json +3 -3
- package/process.d.ts +4 -1
- package/process.js +2 -1
- package/utils.browser.d.ts +3 -2
- package/utils.browser.js +7 -4
- package/utils.d.ts +3 -2
- package/utils.js +7 -4
package/net.browser.d.ts
CHANGED
|
@@ -90,12 +90,14 @@ export declare class WebSocketConnectionError extends Error {
|
|
|
90
90
|
- on_error?: 在 websocket 出错和非正常关闭 (close, error 事件) 时都调用,可以根据 error.type 来区分,error 的类型是 WebSocketConnectionError,
|
|
91
91
|
type 为 'close' 时有 code 和 reason 属性
|
|
92
92
|
- on_close?: 和 websocket 的 'close' 事件不相同,只在正常关闭 (close code 为 1000) 时才调用,否则都会调用 on_error
|
|
93
|
-
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
94
|
-
|
|
93
|
+
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
94
|
+
- print?: 是否打印连接、关闭信息 */
|
|
95
|
+
export declare function connect_websocket(url: string | URL, { protocols, on_message, on_error, on_close, print }: {
|
|
95
96
|
protocols?: string[];
|
|
96
97
|
on_message(data: ArrayBuffer | string, websocket: WebSocket): any;
|
|
97
98
|
on_error?(error: WebSocketConnectionError, websocket: WebSocket): any;
|
|
98
99
|
on_close?(event: CloseEvent, websocket: WebSocket): any;
|
|
100
|
+
print?: boolean;
|
|
99
101
|
}): Promise<WebSocket>;
|
|
100
102
|
/** 接收到消息后的处理函数
|
|
101
103
|
返回值可以是:
|
|
@@ -185,8 +187,10 @@ export declare class Remote {
|
|
|
185
187
|
一元 rpc 接收方不需要设置 handlers, 发送方需要 */
|
|
186
188
|
handlers: Map<number, MessageHandler<any[]>>;
|
|
187
189
|
keeper?: RemoteKeeperOptions;
|
|
188
|
-
/** `
|
|
190
|
+
/** `true` 是否打印连接信息、错误信息 */
|
|
189
191
|
print: boolean;
|
|
192
|
+
/** `false` 打印所有交互的 rpc messages */
|
|
193
|
+
verbose: boolean;
|
|
190
194
|
first_error: boolean;
|
|
191
195
|
keeping: boolean;
|
|
192
196
|
reconnecting: boolean;
|
|
@@ -196,10 +200,11 @@ export declare class Remote {
|
|
|
196
200
|
static pack({ id, func, data, done, error }: Message): Uint8Array;
|
|
197
201
|
/** 作为 websocket 连接发起方,传入 url 或 websocket,定义远程 Remote
|
|
198
202
|
作为 websocket 连接接收方,不传 url 和 websocket,定义本地 Remote */
|
|
199
|
-
constructor({ url, funcs, print, websocket, keeper, on_error, }?: {
|
|
203
|
+
constructor({ url, funcs, print, verbose, websocket, keeper, on_error, }?: {
|
|
200
204
|
url?: string;
|
|
201
205
|
funcs?: Remote['funcs'];
|
|
202
206
|
print?: boolean;
|
|
207
|
+
verbose?: boolean;
|
|
203
208
|
websocket?: WebSocket;
|
|
204
209
|
keeper?: RemoteKeeperOptions;
|
|
205
210
|
on_error?(error: WebSocketConnectionError, websocket?: WebSocket): void;
|
package/net.browser.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t } from './i18n/instance.js';
|
|
2
2
|
import './prototype.browser.js'; // to_time_str()
|
|
3
|
-
import { assert, concat, genid, delay, Lock, encode, decode, timeout } from './utils.browser.js';
|
|
3
|
+
import { assert, concat, genid, delay, Lock, encode, decode, timeout, check } from './utils.browser.js';
|
|
4
4
|
const drop_request_headers = new Set([
|
|
5
5
|
// : 开头的 key
|
|
6
6
|
// sec-*
|
|
@@ -186,26 +186,29 @@ export class WebSocketConnectionError extends Error {
|
|
|
186
186
|
- on_error?: 在 websocket 出错和非正常关闭 (close, error 事件) 时都调用,可以根据 error.type 来区分,error 的类型是 WebSocketConnectionError,
|
|
187
187
|
type 为 'close' 时有 code 和 reason 属性
|
|
188
188
|
- on_close?: 和 websocket 的 'close' 事件不相同,只在正常关闭 (close code 为 1000) 时才调用,否则都会调用 on_error
|
|
189
|
-
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
190
|
-
|
|
189
|
+
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
190
|
+
- print?: 是否打印连接、关闭信息 */
|
|
191
|
+
export async function connect_websocket(url, { protocols, on_message, on_error, on_close, print = true }) {
|
|
191
192
|
let websocket = new WebSocket(url, protocols);
|
|
192
193
|
// https://stackoverflow.com/questions/11821096/what-is-the-difference-between-an-arraybuffer-and-a-blob/39951543
|
|
193
194
|
websocket.binaryType = 'arraybuffer';
|
|
194
195
|
return new Promise((resolve, reject) => {
|
|
195
196
|
let settled = false;
|
|
196
197
|
websocket.addEventListener('open', event => {
|
|
197
|
-
|
|
198
|
-
(websocket.
|
|
199
|
-
|
|
198
|
+
if (print)
|
|
199
|
+
console.log(websocket.url +
|
|
200
|
+
(websocket.protocol ? ' ' + websocket.protocol.bracket() : '') +
|
|
201
|
+
t(' 已连接'));
|
|
200
202
|
settled = true;
|
|
201
203
|
resolve(websocket);
|
|
202
204
|
});
|
|
203
205
|
websocket.addEventListener('close', event => {
|
|
204
|
-
if (event.code === 1000) // 正常关闭
|
|
206
|
+
if (event.code === 1000) { // 正常关闭
|
|
205
207
|
if (on_close)
|
|
206
208
|
on_close(event, websocket);
|
|
207
|
-
else
|
|
209
|
+
else if (print)
|
|
208
210
|
console.log(`${websocket.url} ${t('已正常关闭')}`);
|
|
211
|
+
}
|
|
209
212
|
else { // 异常关闭,认为发生了错误,进行错误处理
|
|
210
213
|
const error = new WebSocketConnectionError(websocket.url, protocols, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
211
214
|
if (settled)
|
|
@@ -278,8 +281,10 @@ export class Remote {
|
|
|
278
281
|
一元 rpc 接收方不需要设置 handlers, 发送方需要 */
|
|
279
282
|
handlers = new Map();
|
|
280
283
|
keeper;
|
|
284
|
+
/** `true` 是否打印连接信息、错误信息 */
|
|
285
|
+
print = true;
|
|
281
286
|
/** `false` 打印所有交互的 rpc messages */
|
|
282
|
-
|
|
287
|
+
verbose = false;
|
|
283
288
|
first_error = true;
|
|
284
289
|
keeping = false;
|
|
285
290
|
reconnecting = false;
|
|
@@ -305,7 +310,6 @@ export class Remote {
|
|
|
305
310
|
return message;
|
|
306
311
|
}
|
|
307
312
|
static pack({ id, func, data = [], done, error }) {
|
|
308
|
-
assert('length' in data, 'message.data 必须是数组');
|
|
309
313
|
let data_ = new Array(data.length);
|
|
310
314
|
let bins = [];
|
|
311
315
|
let bufs = [];
|
|
@@ -335,12 +339,12 @@ export class Remote {
|
|
|
335
339
|
}
|
|
336
340
|
/** 作为 websocket 连接发起方,传入 url 或 websocket,定义远程 Remote
|
|
337
341
|
作为 websocket 连接接收方,不传 url 和 websocket,定义本地 Remote */
|
|
338
|
-
constructor({ url, funcs, print, websocket, keeper, on_error, } = {}) {
|
|
339
|
-
|
|
342
|
+
constructor({ url, funcs, print, verbose, websocket, keeper, on_error, } = {}) {
|
|
343
|
+
check(!(url && websocket), '构建 Remote 时 url 和 websocket 最多只能传一个');
|
|
340
344
|
this.initiator = Boolean(url || websocket);
|
|
341
345
|
if (url)
|
|
342
346
|
this.url = url;
|
|
343
|
-
|
|
347
|
+
check(!funcs?.echo);
|
|
344
348
|
this.funcs = this.initiator ? funcs : {
|
|
345
349
|
...funcs,
|
|
346
350
|
echo({ data }) {
|
|
@@ -349,12 +353,14 @@ export class Remote {
|
|
|
349
353
|
};
|
|
350
354
|
if (print !== undefined)
|
|
351
355
|
this.print = print;
|
|
356
|
+
if (verbose !== undefined)
|
|
357
|
+
this.verbose = verbose;
|
|
352
358
|
if (on_error)
|
|
353
359
|
this.on_error = on_error;
|
|
354
360
|
if (this.initiator)
|
|
355
361
|
this.lwebsocket = new Lock(websocket || null);
|
|
356
362
|
if (keeper) {
|
|
357
|
-
|
|
363
|
+
check(this.initiator && url);
|
|
358
364
|
this.keeper = {
|
|
359
365
|
reconnect_interval: 1000 * 5,
|
|
360
366
|
heartbeat_interval: 1000 * 60,
|
|
@@ -380,14 +386,13 @@ export class Remote {
|
|
|
380
386
|
this.reconnecting = false;
|
|
381
387
|
if (!this.disconnected)
|
|
382
388
|
try {
|
|
383
|
-
await timeout(3000, async () => {
|
|
384
|
-
await this.connect();
|
|
385
|
-
});
|
|
389
|
+
await timeout(3000, async () => { await this.connect(); }, undefined, this.print);
|
|
386
390
|
this.first_error = true;
|
|
387
391
|
}
|
|
388
392
|
catch (error) {
|
|
389
393
|
// 重连失败的错误这里需要简单打印下,_on_error 不会打印,这里也不继续往上抛了
|
|
390
|
-
|
|
394
|
+
if (this.print)
|
|
395
|
+
console.log(error.message);
|
|
391
396
|
// 重连由 this.connect 里面调用 this._on_error 处理
|
|
392
397
|
}
|
|
393
398
|
})();
|
|
@@ -397,8 +402,10 @@ export class Remote {
|
|
|
397
402
|
};
|
|
398
403
|
/** 使用者自定义的在连接后出错时的处理 */
|
|
399
404
|
on_error(error, websocket) {
|
|
400
|
-
if (this.keeper)
|
|
401
|
-
|
|
405
|
+
if (this.keeper) {
|
|
406
|
+
if (this.print)
|
|
407
|
+
console.log(error.message);
|
|
408
|
+
}
|
|
402
409
|
else
|
|
403
410
|
throw error;
|
|
404
411
|
}
|
|
@@ -424,7 +431,8 @@ export class Remote {
|
|
|
424
431
|
try {
|
|
425
432
|
this.lwebsocket.resource = await connect_websocket(this.url, {
|
|
426
433
|
on_message: this._on_message,
|
|
427
|
-
on_error: this._on_error
|
|
434
|
+
on_error: this._on_error,
|
|
435
|
+
print: this.print
|
|
428
436
|
});
|
|
429
437
|
reconnected = true;
|
|
430
438
|
}
|
|
@@ -446,12 +454,11 @@ export class Remote {
|
|
|
446
454
|
break;
|
|
447
455
|
if (!this.reconnecting)
|
|
448
456
|
try {
|
|
449
|
-
await timeout(1000 * 2, async () => {
|
|
450
|
-
await this.call('echo', []);
|
|
451
|
-
});
|
|
457
|
+
await timeout(1000 * 2, async () => { await this.call('echo', []); }, undefined, this.print);
|
|
452
458
|
}
|
|
453
459
|
catch (error) {
|
|
454
|
-
|
|
460
|
+
if (this.print)
|
|
461
|
+
console.log(error.message);
|
|
455
462
|
this._on_error(error);
|
|
456
463
|
}
|
|
457
464
|
}
|
|
@@ -474,8 +481,8 @@ export class Remote {
|
|
|
474
481
|
作为 websocket 连接接收方,必传 websocket 参数
|
|
475
482
|
发送或连接出错时自动清理 message.id 对应的 handler */
|
|
476
483
|
async send(message, websocket) {
|
|
477
|
-
|
|
478
|
-
if (this.
|
|
484
|
+
check(!message.data || message.data.every(arg => arg !== undefined), `message.data 数组中不能有 undefined 的项, 因为 json 序列化后会变为 null. (func: ${message.func}, id: ${message.id})`);
|
|
485
|
+
if (this.verbose)
|
|
479
486
|
console.log('remote.send:', message);
|
|
480
487
|
try {
|
|
481
488
|
await this.connect(websocket);
|
|
@@ -496,7 +503,7 @@ export class Remote {
|
|
|
496
503
|
async handle(data, websocket) {
|
|
497
504
|
const message = Remote.parse(data);
|
|
498
505
|
const { id, func, done } = message;
|
|
499
|
-
if (this.
|
|
506
|
+
if (this.verbose)
|
|
500
507
|
console.log('remote.handle:', message);
|
|
501
508
|
let handler;
|
|
502
509
|
if (func)
|
package/net.d.ts
CHANGED
|
@@ -147,15 +147,17 @@ export declare class WebSocketConnectionError extends Error {
|
|
|
147
147
|
- on_error?: 在 websocket 出错和非正常关闭 (close, error 事件) 时都调用,可以根据 error.type 来区分,error 的类型是 WebSocketConnectionError,
|
|
148
148
|
type 为 'close' 时有 code 和 reason 属性
|
|
149
149
|
- on_close?: 和 websocket 的 'close' 事件不相同,只在正常关闭 (close code 为 1000) 时才调用,否则都会调用 on_error
|
|
150
|
-
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
150
|
+
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
151
|
+
- print?: 是否打印连接、关闭信息 */
|
|
151
152
|
export declare function connect_websocket(url: string | URL, { protocols, max_payload, // 8 GB
|
|
152
|
-
on_message, on_error, on_close, proxy }: {
|
|
153
|
+
on_message, on_error, on_close, proxy, print, }: {
|
|
153
154
|
protocols?: string[];
|
|
154
155
|
max_payload?: number;
|
|
155
156
|
on_message(data: ArrayBuffer | string, websocket: WebSocket): any;
|
|
156
157
|
on_error?(error: WebSocketConnectionError, websocket: WebSocket): any;
|
|
157
158
|
on_close?(event: CloseEvent, websocket: WebSocket): any;
|
|
158
159
|
proxy?: string;
|
|
160
|
+
print?: boolean;
|
|
159
161
|
}): Promise<WebSocket>;
|
|
160
162
|
/** 接收到消息后的处理函数
|
|
161
163
|
返回值可以是:
|
|
@@ -245,8 +247,10 @@ export declare class Remote {
|
|
|
245
247
|
一元 rpc 接收方不需要设置 handlers, 发送方需要 */
|
|
246
248
|
handlers: Map<number, MessageHandler<any[]>>;
|
|
247
249
|
keeper?: RemoteKeeperOptions;
|
|
248
|
-
/** `
|
|
250
|
+
/** `true` 是否打印连接信息、错误信息 */
|
|
249
251
|
print: boolean;
|
|
252
|
+
/** `false` 打印所有交互的 rpc messages */
|
|
253
|
+
verbose: boolean;
|
|
250
254
|
first_error: boolean;
|
|
251
255
|
keeping: boolean;
|
|
252
256
|
reconnecting: boolean;
|
|
@@ -256,10 +260,11 @@ export declare class Remote {
|
|
|
256
260
|
static pack({ id, func, data, done, error }: Message): Uint8Array;
|
|
257
261
|
/** 作为 websocket 连接发起方,传入 url 或 websocket,定义远程 Remote
|
|
258
262
|
作为 websocket 连接接收方,不传 url 和 websocket,定义本地 Remote */
|
|
259
|
-
constructor({ url, funcs, print, websocket, keeper, on_error, }?: {
|
|
263
|
+
constructor({ url, funcs, print, verbose, websocket, keeper, on_error, }?: {
|
|
260
264
|
url?: string;
|
|
261
265
|
funcs?: Remote['funcs'];
|
|
262
266
|
print?: boolean;
|
|
267
|
+
verbose?: boolean;
|
|
263
268
|
websocket?: WebSocket;
|
|
264
269
|
keeper?: RemoteKeeperOptions;
|
|
265
270
|
on_error?(error: WebSocketConnectionError, websocket?: WebSocket): void;
|
package/net.js
CHANGED
|
@@ -3,7 +3,7 @@ import { buffer as stream_to_buffer, text as stream_to_text } from 'stream/consu
|
|
|
3
3
|
import { isReadable } from 'stream';
|
|
4
4
|
import { t } from './i18n/instance.js';
|
|
5
5
|
import './prototype.js';
|
|
6
|
-
import { inspect, concat, assert, genid, delay, Lock, encode, decode, pipe_with_error, map_values, unique, timeout } from './utils.js';
|
|
6
|
+
import { inspect, concat, assert, genid, delay, Lock, encode, decode, pipe_with_error, map_values, unique, timeout, check } from './utils.js';
|
|
7
7
|
export const WebSocketConnecting = 0;
|
|
8
8
|
export const WebSocketOpen = 1;
|
|
9
9
|
export const WebSocketClosing = 2;
|
|
@@ -396,9 +396,10 @@ let websocket_proxy_agents = {};
|
|
|
396
396
|
- on_error?: 在 websocket 出错和非正常关闭 (close, error 事件) 时都调用,可以根据 error.type 来区分,error 的类型是 WebSocketConnectionError,
|
|
397
397
|
type 为 'close' 时有 code 和 reason 属性
|
|
398
398
|
- on_close?: 和 websocket 的 'close' 事件不相同,只在正常关闭 (close code 为 1000) 时才调用,否则都会调用 on_error
|
|
399
|
-
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
399
|
+
https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes
|
|
400
|
+
- print?: 是否打印连接、关闭信息 */
|
|
400
401
|
export async function connect_websocket(url, { protocols, max_payload = 2 ** 33, // 8 GB
|
|
401
|
-
on_message, on_error, on_close, proxy }) {
|
|
402
|
+
on_message, on_error, on_close, proxy, print = true, }) {
|
|
402
403
|
const { WebSocket } = await import('ws');
|
|
403
404
|
const { HttpsProxyAgent } = await import('https-proxy-agent');
|
|
404
405
|
let websocket = new WebSocket(url, protocols, {
|
|
@@ -414,9 +415,10 @@ on_message, on_error, on_close, proxy }) {
|
|
|
414
415
|
return new Promise((resolve, reject) => {
|
|
415
416
|
let settled = false;
|
|
416
417
|
websocket.addEventListener('open', event => {
|
|
417
|
-
|
|
418
|
-
(websocket.
|
|
419
|
-
|
|
418
|
+
if (print)
|
|
419
|
+
console.log(websocket.url +
|
|
420
|
+
(websocket.protocol ? ' ' + websocket.protocol.bracket() : '') +
|
|
421
|
+
t(' 已连接'));
|
|
420
422
|
settled = true;
|
|
421
423
|
resolve(websocket);
|
|
422
424
|
});
|
|
@@ -426,13 +428,14 @@ on_message, on_error, on_close, proxy }) {
|
|
|
426
428
|
// 接着马上 close 事件也被调用,此时 settled,马上调用了 on_error 函数,弄乱了顺序
|
|
427
429
|
// error 的错误信息比较多,而且通过 await 得到的栈也比较清晰,这里延后调用 on_close 和 on_error,放到微任务队列之后的 timers 队列中
|
|
428
430
|
setTimeout(() => {
|
|
429
|
-
if (event.code === 1000) // 正常关闭
|
|
431
|
+
if (event.code === 1000) { // 正常关闭
|
|
430
432
|
if (on_close)
|
|
431
433
|
on_close(event, websocket);
|
|
432
|
-
else
|
|
434
|
+
else if (print)
|
|
433
435
|
console.log(`${websocket.url} ${t('已正常关闭')}`);
|
|
436
|
+
}
|
|
434
437
|
else { // 异常关闭,认为发生了错误,进行错误处理
|
|
435
|
-
|
|
438
|
+
// websocket close 事件时已经 settled
|
|
436
439
|
const error = new WebSocketConnectionError(websocket.url, protocols, event, `${t('连接被关闭')}, code: ${event.code}${event.reason ? `, ${t('原因')}: ${event.reason}` : ''}`);
|
|
437
440
|
if (on_error)
|
|
438
441
|
on_error(error, websocket);
|
|
@@ -496,8 +499,10 @@ export class Remote {
|
|
|
496
499
|
一元 rpc 接收方不需要设置 handlers, 发送方需要 */
|
|
497
500
|
handlers = new Map();
|
|
498
501
|
keeper;
|
|
502
|
+
/** `true` 是否打印连接信息、错误信息 */
|
|
503
|
+
print = true;
|
|
499
504
|
/** `false` 打印所有交互的 rpc messages */
|
|
500
|
-
|
|
505
|
+
verbose = false;
|
|
501
506
|
first_error = true;
|
|
502
507
|
keeping = false;
|
|
503
508
|
reconnecting = false;
|
|
@@ -523,7 +528,6 @@ export class Remote {
|
|
|
523
528
|
return message;
|
|
524
529
|
}
|
|
525
530
|
static pack({ id, func, data = [], done, error }) {
|
|
526
|
-
assert('length' in data, 'message.data 必须是数组');
|
|
527
531
|
let data_ = new Array(data.length);
|
|
528
532
|
let bins = [];
|
|
529
533
|
let bufs = [];
|
|
@@ -553,12 +557,12 @@ export class Remote {
|
|
|
553
557
|
}
|
|
554
558
|
/** 作为 websocket 连接发起方,传入 url 或 websocket,定义远程 Remote
|
|
555
559
|
作为 websocket 连接接收方,不传 url 和 websocket,定义本地 Remote */
|
|
556
|
-
constructor({ url, funcs, print, websocket, keeper, on_error, } = {}) {
|
|
557
|
-
|
|
560
|
+
constructor({ url, funcs, print, verbose, websocket, keeper, on_error, } = {}) {
|
|
561
|
+
check(!(url && websocket), '构建 Remote 时 url 和 websocket 最多只能传一个');
|
|
558
562
|
this.initiator = Boolean(url || websocket);
|
|
559
563
|
if (url)
|
|
560
564
|
this.url = url;
|
|
561
|
-
|
|
565
|
+
check(!funcs?.echo);
|
|
562
566
|
this.funcs = this.initiator ? funcs : {
|
|
563
567
|
...funcs,
|
|
564
568
|
echo({ data }) {
|
|
@@ -567,12 +571,14 @@ export class Remote {
|
|
|
567
571
|
};
|
|
568
572
|
if (print !== undefined)
|
|
569
573
|
this.print = print;
|
|
574
|
+
if (verbose !== undefined)
|
|
575
|
+
this.verbose = verbose;
|
|
570
576
|
if (on_error)
|
|
571
577
|
this.on_error = on_error;
|
|
572
578
|
if (this.initiator)
|
|
573
579
|
this.lwebsocket = new Lock(websocket || null);
|
|
574
580
|
if (keeper) {
|
|
575
|
-
|
|
581
|
+
check(this.initiator && url);
|
|
576
582
|
this.keeper = {
|
|
577
583
|
reconnect_interval: 1000 * 5,
|
|
578
584
|
heartbeat_interval: 1000 * 60,
|
|
@@ -598,14 +604,13 @@ export class Remote {
|
|
|
598
604
|
this.reconnecting = false;
|
|
599
605
|
if (!this.disconnected)
|
|
600
606
|
try {
|
|
601
|
-
await timeout(3000, async () => {
|
|
602
|
-
await this.connect();
|
|
603
|
-
});
|
|
607
|
+
await timeout(3000, async () => { await this.connect(); }, undefined, this.print);
|
|
604
608
|
this.first_error = true;
|
|
605
609
|
}
|
|
606
610
|
catch (error) {
|
|
607
611
|
// 重连失败的错误这里需要简单打印下,_on_error 不会打印,这里也不继续往上抛了
|
|
608
|
-
|
|
612
|
+
if (this.print)
|
|
613
|
+
console.log(error.message);
|
|
609
614
|
// 重连由 this.connect 里面调用 this._on_error 处理
|
|
610
615
|
}
|
|
611
616
|
})();
|
|
@@ -615,8 +620,10 @@ export class Remote {
|
|
|
615
620
|
};
|
|
616
621
|
/** 使用者自定义的在连接后出错时的处理 */
|
|
617
622
|
on_error(error, websocket) {
|
|
618
|
-
if (this.keeper)
|
|
619
|
-
|
|
623
|
+
if (this.keeper) {
|
|
624
|
+
if (this.print)
|
|
625
|
+
console.log(error.message);
|
|
626
|
+
}
|
|
620
627
|
else
|
|
621
628
|
throw error;
|
|
622
629
|
}
|
|
@@ -642,7 +649,8 @@ export class Remote {
|
|
|
642
649
|
try {
|
|
643
650
|
this.lwebsocket.resource = await connect_websocket(this.url, {
|
|
644
651
|
on_message: this._on_message,
|
|
645
|
-
on_error: this._on_error
|
|
652
|
+
on_error: this._on_error,
|
|
653
|
+
print: this.print
|
|
646
654
|
});
|
|
647
655
|
reconnected = true;
|
|
648
656
|
}
|
|
@@ -664,12 +672,11 @@ export class Remote {
|
|
|
664
672
|
break;
|
|
665
673
|
if (!this.reconnecting)
|
|
666
674
|
try {
|
|
667
|
-
await timeout(1000 * 2, async () => {
|
|
668
|
-
await this.call('echo', []);
|
|
669
|
-
});
|
|
675
|
+
await timeout(1000 * 2, async () => { await this.call('echo', []); }, undefined, this.print);
|
|
670
676
|
}
|
|
671
677
|
catch (error) {
|
|
672
|
-
|
|
678
|
+
if (this.print)
|
|
679
|
+
console.log(error.message);
|
|
673
680
|
this._on_error(error);
|
|
674
681
|
}
|
|
675
682
|
}
|
|
@@ -692,8 +699,8 @@ export class Remote {
|
|
|
692
699
|
作为 websocket 连接接收方,必传 websocket 参数
|
|
693
700
|
发送或连接出错时自动清理 message.id 对应的 handler */
|
|
694
701
|
async send(message, websocket) {
|
|
695
|
-
|
|
696
|
-
if (this.
|
|
702
|
+
check(!message.data || message.data.every(arg => arg !== undefined), `message.data 数组中不能有 undefined 的项, 因为 json 序列化后会变为 null. (func: ${message.func}, id: ${message.id})`);
|
|
703
|
+
if (this.verbose)
|
|
697
704
|
console.log('remote.send:', message);
|
|
698
705
|
try {
|
|
699
706
|
await this.connect(websocket);
|
|
@@ -714,7 +721,7 @@ export class Remote {
|
|
|
714
721
|
async handle(data, websocket) {
|
|
715
722
|
const message = Remote.parse(data);
|
|
716
723
|
const { id, func, done } = message;
|
|
717
|
-
if (this.
|
|
724
|
+
if (this.verbose)
|
|
718
725
|
console.log('remote.handle:', message);
|
|
719
726
|
let handler;
|
|
720
727
|
if (func)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xshell",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.199",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"bin": {
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"gulp-sort": "^2.0.0",
|
|
82
82
|
"hash-string": "^1.0.0",
|
|
83
83
|
"https-proxy-agent": "^7.0.5",
|
|
84
|
-
"i18next": "^23.16.
|
|
84
|
+
"i18next": "^23.16.8",
|
|
85
85
|
"i18next-scanner": "^4.6.0",
|
|
86
86
|
"koa": "^2.15.3",
|
|
87
87
|
"koa-compress": "^5.1.1",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"@types/koa-compress": "^4.0.6",
|
|
127
127
|
"@types/lodash": "^4.17.13",
|
|
128
128
|
"@types/mime-types": "^2.1.4",
|
|
129
|
-
"@types/node": "^22.9.
|
|
129
|
+
"@types/node": "^22.9.1",
|
|
130
130
|
"@types/react": "^18.3.12",
|
|
131
131
|
"@types/through2": "^2.0.41",
|
|
132
132
|
"@types/tough-cookie": "^4.0.5",
|
package/process.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ export interface CallOptions extends StartOptions {
|
|
|
82
82
|
stdout?: (chunk: string) => void;
|
|
83
83
|
stderr?: (chunk: string) => void;
|
|
84
84
|
};
|
|
85
|
+
on_child?: (child: ChildProcess) => void;
|
|
85
86
|
}
|
|
86
87
|
export interface CallResult<TOutput extends string | Buffer = string> {
|
|
87
88
|
pid: number;
|
|
@@ -111,10 +112,12 @@ export interface CallError {
|
|
|
111
112
|
- encoding?: `'utf-8'` 子进程输出编码, 设置为 binary 时返回 stdout, stderr 类型为 Buffer; 否则是 string
|
|
112
113
|
child output encoding. When set to binary, return stdout, stderr is of type Buffer; otherwise it is string
|
|
113
114
|
- print?: `true` print 选项,支持设置细项 print option (with details)
|
|
115
|
+
- printers?: 实时处理 stdout 和 stderr 的每个 chunk
|
|
114
116
|
- stdio?: `'pipe'` 设置为 'ignore' 时忽略 stdio 处理 when 'ignore' then ignore stdio processing
|
|
115
117
|
- input?: string, 启动子进程之后写入到子进程 stdin 中的内容,写完后关闭子进程 stdin (pty 不关闭)
|
|
116
118
|
- detached?: `false` 是否断开和 child 的关系 (ignore stdio, unref) whether to break the connection with child (ignore stdio, unref)
|
|
117
|
-
- throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0
|
|
119
|
+
- throw_code?: `true` code 不为 0 时是否抛出异常 whether to throw Error when code is not 0
|
|
120
|
+
- on_child: 可以传入回调函数及时获取通过 start 创建的子进程,便于执行 kill、获得 pid 等操作 */
|
|
118
121
|
export declare function call(exe: string, args?: string[]): Promise<CallResult<string>>;
|
|
119
122
|
export declare function call(exe: string, args?: string[], options?: CallOptions & {
|
|
120
123
|
encoding: 'binary';
|
package/process.js
CHANGED
|
@@ -116,7 +116,7 @@ export async function start_nodejs(js, args = [], options) {
|
|
|
116
116
|
return start(exe_nodejs, [js, ...args], options);
|
|
117
117
|
}
|
|
118
118
|
export async function call(exe, args = [], options = {}) {
|
|
119
|
-
const { encoding = 'utf-8', throw_code = true, printers } = options;
|
|
119
|
+
const { encoding = 'utf-8', throw_code = true, printers, on_child } = options;
|
|
120
120
|
let { stdio = 'pipe', print = true } = options;
|
|
121
121
|
if (typeof print === 'boolean')
|
|
122
122
|
print = {
|
|
@@ -138,6 +138,7 @@ export async function call(exe, args = [], options = {}) {
|
|
|
138
138
|
...options,
|
|
139
139
|
print: false,
|
|
140
140
|
});
|
|
141
|
+
on_child?.(child);
|
|
141
142
|
// --- collect output
|
|
142
143
|
let stdouts = [];
|
|
143
144
|
let stderrs = [];
|
package/utils.browser.d.ts
CHANGED
|
@@ -28,8 +28,9 @@ export declare class TimeoutError extends Error {
|
|
|
28
28
|
}
|
|
29
29
|
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
|
|
30
30
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
|
|
31
|
-
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
32
|
-
|
|
31
|
+
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
32
|
+
- print?: 打印已超时任务的错误 */
|
|
33
|
+
export declare function timeout<TReturn>(milliseconds: number, action: () => Promise<TReturn>, on_timeout?: () => void | Promise<void>, print?: boolean): Promise<TReturn>;
|
|
33
34
|
/** https://stackoverflow.com/questions/63297164/how-to-only-accept-arraybuffer-as-parameter */
|
|
34
35
|
export type StrictArrayBuffer = ArrayBuffer & {
|
|
35
36
|
buffer?: undefined;
|
package/utils.browser.js
CHANGED
|
@@ -80,8 +80,9 @@ export class TimeoutError extends Error {
|
|
|
80
80
|
}
|
|
81
81
|
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
|
|
82
82
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
|
|
83
|
-
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
84
|
-
|
|
83
|
+
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
84
|
+
- print?: 打印已超时任务的错误 */
|
|
85
|
+
export async function timeout(milliseconds, action, on_timeout, print = true) {
|
|
85
86
|
const error = new TimeoutError();
|
|
86
87
|
return new Promise((resolve, reject) => {
|
|
87
88
|
let done = false;
|
|
@@ -112,8 +113,10 @@ export async function timeout(milliseconds, action, on_timeout) {
|
|
|
112
113
|
resolve(await action());
|
|
113
114
|
}
|
|
114
115
|
catch (error) {
|
|
115
|
-
if (rejected)
|
|
116
|
-
|
|
116
|
+
if (rejected) {
|
|
117
|
+
if (print)
|
|
118
|
+
console.log(`已超时任务的错误: ${error.message}`);
|
|
119
|
+
}
|
|
117
120
|
else {
|
|
118
121
|
rejected = true;
|
|
119
122
|
reject(error);
|
package/utils.d.ts
CHANGED
|
@@ -89,8 +89,9 @@ export declare class TimeoutError extends Error {
|
|
|
89
89
|
}
|
|
90
90
|
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
|
|
91
91
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
|
|
92
|
-
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
93
|
-
|
|
92
|
+
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
93
|
+
- print?: 打印已超时任务的错误 */
|
|
94
|
+
export declare function timeout<TReturn>(milliseconds: number, action: () => Promise<TReturn>, on_timeout?: () => void | Promise<void>, print?: boolean): Promise<TReturn>;
|
|
94
95
|
/** https://stackoverflow.com/questions/63297164/how-to-only-accept-arraybuffer-as-parameter */
|
|
95
96
|
export type StrictArrayBuffer = ArrayBuffer & {
|
|
96
97
|
buffer?: undefined;
|
package/utils.js
CHANGED
|
@@ -251,8 +251,9 @@ export class TimeoutError extends Error {
|
|
|
251
251
|
}
|
|
252
252
|
/** 在指定的时间 (milliseconds) 内运行某个任务,超时之后
|
|
253
253
|
- 如果传入了 on_timeout 参数: 调用 on_timeout,返回 null
|
|
254
|
-
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
255
|
-
|
|
254
|
+
- 如果没传入 on_timeout 参数: 抛出 TimeoutError
|
|
255
|
+
- print?: 打印已超时任务的错误 */
|
|
256
|
+
export async function timeout(milliseconds, action, on_timeout, print = true) {
|
|
256
257
|
const error = new TimeoutError();
|
|
257
258
|
return new Promise((resolve, reject) => {
|
|
258
259
|
let done = false;
|
|
@@ -283,8 +284,10 @@ export async function timeout(milliseconds, action, on_timeout) {
|
|
|
283
284
|
resolve(await action());
|
|
284
285
|
}
|
|
285
286
|
catch (error) {
|
|
286
|
-
if (rejected)
|
|
287
|
-
|
|
287
|
+
if (rejected) {
|
|
288
|
+
if (print)
|
|
289
|
+
console.log(`已超时任务的错误: ${error.message}`);
|
|
290
|
+
}
|
|
288
291
|
else {
|
|
289
292
|
rejected = true;
|
|
290
293
|
reject(error);
|