node-karin 0.11.15 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/adapter/input/index.d.ts +1 -1
- package/lib/adapter/input/index.js +1 -1
- package/lib/adapter/onebot/11/index.d.ts +1 -1
- package/lib/adapter/onebot/11/index.js +1 -1
- package/lib/core/karin/karin.d.ts +19 -3
- package/lib/core/karin/karin.js +26 -15
- package/lib/render/client.d.ts +11 -0
- package/lib/render/client.js +91 -11
- package/lib/types/adapter/base.d.ts +1 -1
- package/lib/types/logger/logger.d.ts +1 -1
- package/lib/utils/common/common.js +8 -3
- package/package.json +9 -3
- package/lib/render/client_even.d.ts +0 -30
- package/lib/render/client_even.js +0 -156
|
@@ -148,7 +148,7 @@ export class AdapterInput {
|
|
|
148
148
|
getAvatarUrl() {
|
|
149
149
|
return 'https://p.qlogo.cn/gh/967068507/967068507/0';
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
getGroupAvatarUrl() {
|
|
152
152
|
return 'https://p.qlogo.cn/gh/967068507/967068507/0';
|
|
153
153
|
}
|
|
154
154
|
async GetCurrentAccount() {
|
|
@@ -60,7 +60,7 @@ export declare class AdapterOneBot11 implements KarinAdapter {
|
|
|
60
60
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
61
61
|
* @returns - 群头像的url地址
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
getGroupAvatarUrl(group_id: string, size?: number, history?: number): string;
|
|
64
64
|
/**
|
|
65
65
|
* 发送消息
|
|
66
66
|
*
|
|
@@ -161,7 +161,7 @@ export class AdapterOneBot11 {
|
|
|
161
161
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
162
162
|
* @returns - 群头像的url地址
|
|
163
163
|
*/
|
|
164
|
-
|
|
164
|
+
getGroupAvatarUrl(group_id, size = 0, history = 0) {
|
|
165
165
|
return `https://p.qlogo.cn/gh/${group_id}/${group_id}${history ? '_' + history : ''}/` + size;
|
|
166
166
|
}
|
|
167
167
|
/**
|
|
@@ -111,11 +111,27 @@ export declare class Karin extends Listeners {
|
|
|
111
111
|
reject: (msg?: string) => void) => Promise<any>, options?: Omit<Options, 'log'>): HandlerInfo;
|
|
112
112
|
/**
|
|
113
113
|
* 构建contact
|
|
114
|
-
* @param
|
|
115
|
-
* @param
|
|
114
|
+
* @param scene - 场景
|
|
115
|
+
* @param peer - 群号或者用户id
|
|
116
116
|
* @param sub_peer - 子id
|
|
117
117
|
*/
|
|
118
|
-
contact(
|
|
118
|
+
contact(scene: Contact['scene'], peer: Contact['peer'], sub_peer?: Contact['sub_peer']): Contact;
|
|
119
|
+
/**
|
|
120
|
+
* 构建group_contact
|
|
121
|
+
* @param peer - 群号
|
|
122
|
+
*/
|
|
123
|
+
contactGroup(peer: Contact['peer']): Contact;
|
|
124
|
+
/**
|
|
125
|
+
* 构建friend_contact
|
|
126
|
+
* @param peer - 用户id
|
|
127
|
+
*/
|
|
128
|
+
contactFriend(peer: Contact['peer']): Contact;
|
|
129
|
+
/**
|
|
130
|
+
* 构建guild_contact
|
|
131
|
+
* @param peer - 频道id
|
|
132
|
+
* @param sub_peer - 子频道id
|
|
133
|
+
*/
|
|
134
|
+
contactGuild(peer: Contact['peer'], sub_peer: string): Contact;
|
|
119
135
|
/**
|
|
120
136
|
* 快速渲染
|
|
121
137
|
* @param file - 文件路径、http地址
|
package/lib/core/karin/karin.js
CHANGED
|
@@ -97,23 +97,34 @@ export class Karin extends Listeners {
|
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* 构建contact
|
|
100
|
-
* @param
|
|
101
|
-
* @param
|
|
100
|
+
* @param scene - 场景
|
|
101
|
+
* @param peer - 群号或者用户id
|
|
102
102
|
* @param sub_peer - 子id
|
|
103
103
|
*/
|
|
104
|
-
contact(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
contact(scene, peer, sub_peer) {
|
|
105
|
+
return { scene, peer, sub_peer };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 构建group_contact
|
|
109
|
+
* @param peer - 群号
|
|
110
|
+
*/
|
|
111
|
+
contactGroup(peer) {
|
|
112
|
+
return { scene: "group" /* Scene.Group */, peer };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 构建friend_contact
|
|
116
|
+
* @param peer - 用户id
|
|
117
|
+
*/
|
|
118
|
+
contactFriend(peer) {
|
|
119
|
+
return { scene: "friend" /* Scene.Private */, peer };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 构建guild_contact
|
|
123
|
+
* @param peer - 频道id
|
|
124
|
+
* @param sub_peer - 子频道id
|
|
125
|
+
*/
|
|
126
|
+
contactGuild(peer, sub_peer) {
|
|
127
|
+
return { scene: "guild" /* Scene.Guild */, peer, sub_peer };
|
|
117
128
|
}
|
|
118
129
|
/**
|
|
119
130
|
* - 渲染
|
package/lib/render/client.d.ts
CHANGED
|
@@ -7,13 +7,24 @@ export declare class RenderClient extends RenderBase {
|
|
|
7
7
|
id: string;
|
|
8
8
|
index: number;
|
|
9
9
|
retry: number;
|
|
10
|
+
short: boolean;
|
|
10
11
|
reg: RegExp;
|
|
11
12
|
ws: WebSocket;
|
|
13
|
+
protocol?: {
|
|
14
|
+
application: string;
|
|
15
|
+
short: boolean;
|
|
16
|
+
cache: boolean;
|
|
17
|
+
vue: boolean;
|
|
18
|
+
};
|
|
12
19
|
constructor(url: string);
|
|
13
20
|
/**
|
|
14
21
|
* 初始化
|
|
15
22
|
*/
|
|
16
23
|
start(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 创建短连接
|
|
26
|
+
*/
|
|
27
|
+
link(): Promise<void>;
|
|
17
28
|
/**
|
|
18
29
|
* 心跳
|
|
19
30
|
*/
|
package/lib/render/client.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import axios from 'axios';
|
|
2
3
|
import WebSocket from 'ws';
|
|
3
4
|
import { render } from './app.js';
|
|
4
5
|
import { RenderBase } from './base.js';
|
|
5
6
|
import { createHash, randomUUID } from 'crypto';
|
|
6
|
-
import {
|
|
7
|
+
import { karin } from '../core/index.js';
|
|
7
8
|
import { common, logger } from '../utils/index.js';
|
|
8
9
|
export class RenderClient extends RenderBase {
|
|
9
10
|
url;
|
|
@@ -11,8 +12,11 @@ export class RenderClient extends RenderBase {
|
|
|
11
12
|
id;
|
|
12
13
|
index;
|
|
13
14
|
retry;
|
|
15
|
+
short;
|
|
14
16
|
reg;
|
|
15
17
|
ws;
|
|
18
|
+
// NOTE: 渲染器协议暂定方案,目前仅short用于短连接模式确认,其他无用
|
|
19
|
+
protocol;
|
|
16
20
|
constructor(url) {
|
|
17
21
|
super();
|
|
18
22
|
this.url = url;
|
|
@@ -20,6 +24,7 @@ export class RenderClient extends RenderBase {
|
|
|
20
24
|
this.id = 'puppeteer';
|
|
21
25
|
this.index = 0;
|
|
22
26
|
this.retry = 0;
|
|
27
|
+
this.short = false;
|
|
23
28
|
this.reg = new RegExp(`(${process.cwd().replace(/\\/g, '\\\\')}|${process.cwd().replace(/\\/g, '/')})`, 'g');
|
|
24
29
|
}
|
|
25
30
|
/**
|
|
@@ -64,22 +69,73 @@ export class RenderClient extends RenderBase {
|
|
|
64
69
|
this.ws.close();
|
|
65
70
|
});
|
|
66
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 创建短连接
|
|
74
|
+
*/
|
|
75
|
+
async link() {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
78
|
+
return resolve();
|
|
79
|
+
}
|
|
80
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 创建短连接`);
|
|
81
|
+
/** 连接ws */
|
|
82
|
+
this.ws = new WebSocket(this.url);
|
|
83
|
+
/** 建立连接 */
|
|
84
|
+
this.ws.on('open', () => {
|
|
85
|
+
logger.mark(`[渲染器:${this.id}][WebSocket] 建立连接:${logger.green(this.url)}`);
|
|
86
|
+
/** 监听消息 */
|
|
87
|
+
this.ws.on('message', data => this.message(data.toString()));
|
|
88
|
+
resolve();
|
|
89
|
+
});
|
|
90
|
+
/** 监听断开 */
|
|
91
|
+
this.ws.once('close', async () => {
|
|
92
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 关闭短连接`);
|
|
93
|
+
/** 停止监听 */
|
|
94
|
+
this.ws.removeAllListeners();
|
|
95
|
+
});
|
|
96
|
+
/** 监听错误 */
|
|
97
|
+
this.ws.on('error', async (e) => {
|
|
98
|
+
logger.debug(e);
|
|
99
|
+
this.ws.close();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
67
103
|
/**
|
|
68
104
|
* 心跳
|
|
69
105
|
*/
|
|
70
106
|
async heartbeat() {
|
|
71
107
|
/** 无限循环 错误则停止 */
|
|
72
108
|
while (true) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
if (this.short) {
|
|
110
|
+
try {
|
|
111
|
+
const res = await axios.head(this.url);
|
|
112
|
+
if (res.status === 200) {
|
|
113
|
+
logger.debug(`[渲染器:${this.id}] 心跳:${this.url}`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:服务器错误,错误代码 ${res.status}`);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:`, e);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
// NOTE: 真的需要心跳的这么快吗
|
|
125
|
+
await common.sleep(60 * 1000);
|
|
76
126
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
127
|
+
else {
|
|
128
|
+
try {
|
|
129
|
+
this.ws.send(JSON.stringify({ action: 'heartbeat' }));
|
|
130
|
+
logger.debug(`[渲染器:${this.id}] 心跳:${this.url}`);
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:`, e);
|
|
134
|
+
this.ws.close();
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
await common.sleep(5000);
|
|
81
138
|
}
|
|
82
|
-
await common.sleep(5000);
|
|
83
139
|
}
|
|
84
140
|
}
|
|
85
141
|
/**
|
|
@@ -101,7 +157,28 @@ export class RenderClient extends RenderBase {
|
|
|
101
157
|
}
|
|
102
158
|
/** 渲染结果 */
|
|
103
159
|
case 'renderRes': {
|
|
104
|
-
|
|
160
|
+
karin.emit(data.echo, data);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
/** 超时 */
|
|
164
|
+
case 'timeout': {
|
|
165
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 处理超时`);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
/** 确认协议 */
|
|
169
|
+
case 'protocol': {
|
|
170
|
+
// 已确认协议,跳过
|
|
171
|
+
if (this.protocol)
|
|
172
|
+
break;
|
|
173
|
+
if (data.data)
|
|
174
|
+
this.protocol = data.data;
|
|
175
|
+
// 短连接模式
|
|
176
|
+
if (data.data?.short) {
|
|
177
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 切换到短连接模式`);
|
|
178
|
+
this.short = data.data?.short;
|
|
179
|
+
this.ws.removeAllListeners();
|
|
180
|
+
this.ws.close();
|
|
181
|
+
}
|
|
105
182
|
break;
|
|
106
183
|
}
|
|
107
184
|
/** 未知数据 */
|
|
@@ -146,9 +223,12 @@ export class RenderClient extends RenderBase {
|
|
|
146
223
|
data.file = file;
|
|
147
224
|
const req = JSON.stringify({ echo, action, data });
|
|
148
225
|
logger.debug(`[渲染器:${this.id}:${this.index}][正向WS] 请求:${this.url} \nhtml: ${options.file} \ndata: ${JSON.stringify(data)}`);
|
|
226
|
+
if (this.short) {
|
|
227
|
+
await this.link();
|
|
228
|
+
}
|
|
149
229
|
this.ws.send(req);
|
|
150
230
|
return new Promise((resolve, reject) => {
|
|
151
|
-
|
|
231
|
+
karin.once(echo, (data) => {
|
|
152
232
|
if (data.ok)
|
|
153
233
|
return resolve(data.data);
|
|
154
234
|
reject(new Error(JSON.stringify(data)));
|
|
@@ -109,7 +109,7 @@ export interface KarinAdapter {
|
|
|
109
109
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
110
110
|
* @returns 头像的url地址
|
|
111
111
|
*/
|
|
112
|
-
|
|
112
|
+
getGroupAvatarUrl(group_id: string, size?: 0 | 40 | 100 | 140, history?: number): string;
|
|
113
113
|
/**
|
|
114
114
|
* 发送消息
|
|
115
115
|
* @param contact - 联系人信息
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
export type LoggerLevel = 'trace' | 'debug' | 'mark' | 'info' | 'mark' | 'warn' | 'error' | 'fatal';
|
|
2
|
+
export type LoggerLevel = 'all' | 'trace' | 'debug' | 'mark' | 'info' | 'mark' | 'warn' | 'error' | 'fatal' | 'off';
|
|
3
3
|
export interface Logger {
|
|
4
4
|
/**
|
|
5
5
|
* 颜色模块
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import Yaml from 'yaml';
|
|
4
|
-
import axios from 'axios';
|
|
4
|
+
import axios, { AxiosError } from 'axios';
|
|
5
5
|
import lodash from 'lodash';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
@@ -38,7 +38,12 @@ export class Common {
|
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
catch (err) {
|
|
41
|
-
|
|
41
|
+
if (err instanceof AxiosError) {
|
|
42
|
+
logger.error(`下载文件错误:${err.stack}`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
logger.error(`下载文件错误:${err}`);
|
|
46
|
+
}
|
|
42
47
|
return false;
|
|
43
48
|
}
|
|
44
49
|
}
|
|
@@ -55,7 +60,7 @@ export class Common {
|
|
|
55
60
|
return await axios.get(url, param);
|
|
56
61
|
}
|
|
57
62
|
catch (error) {
|
|
58
|
-
logger.debug(error);
|
|
63
|
+
error instanceof AxiosError ? logger.debug(error.stack) : logger.debug(error);
|
|
59
64
|
return null;
|
|
60
65
|
}
|
|
61
66
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-karin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "基于 Kritor 进行开发的nodejs机器人框架",
|
|
6
6
|
"homepage": "https://github.com/KarinJS/Karin",
|
|
@@ -133,7 +133,7 @@
|
|
|
133
133
|
],
|
|
134
134
|
"scripts": {
|
|
135
135
|
".": "node lib/cli/start.js .",
|
|
136
|
-
"build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
|
|
136
|
+
"build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json && npm run fix:all",
|
|
137
137
|
"build:npm": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
|
|
138
138
|
"dev": "node lib/cli/start.js dev",
|
|
139
139
|
"fix": "eslint lib/**/*.js --fix",
|
|
@@ -143,12 +143,18 @@
|
|
|
143
143
|
"start": "node lib/cli/start.js start"
|
|
144
144
|
},
|
|
145
145
|
"dependencies": {
|
|
146
|
+
"@types/express": "^4.17.21",
|
|
147
|
+
"@types/lodash": "^4.17.7",
|
|
148
|
+
"@types/node": "^22.5.0",
|
|
149
|
+
"@types/node-schedule": "^2.1.7",
|
|
150
|
+
"@types/ws": "^8.5.12",
|
|
146
151
|
"art-template": "4.13.2",
|
|
147
|
-
"axios": "1.7.
|
|
152
|
+
"axios": "1.7.5",
|
|
148
153
|
"chalk": "5.3.0",
|
|
149
154
|
"chokidar": "3.6.0",
|
|
150
155
|
"commander": "^12.1.0",
|
|
151
156
|
"express": "4.19.2",
|
|
157
|
+
"jimp": "^0.22.12",
|
|
152
158
|
"level": "8.0.1",
|
|
153
159
|
"lodash": "4.17.21",
|
|
154
160
|
"log4js": "6.9.1",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import WebSocket from 'ws';
|
|
2
|
-
import { RenderBase } from './base.js';
|
|
3
|
-
import { KarinRenderType, RenderResult } from '../types/index.js';
|
|
4
|
-
export declare class RenderClientEven extends RenderBase {
|
|
5
|
-
url: string;
|
|
6
|
-
type: string;
|
|
7
|
-
id: string;
|
|
8
|
-
index: number;
|
|
9
|
-
retry: number;
|
|
10
|
-
reg: RegExp;
|
|
11
|
-
ws: WebSocket;
|
|
12
|
-
constructor(url: string);
|
|
13
|
-
/**
|
|
14
|
-
* 初始化
|
|
15
|
-
*/
|
|
16
|
-
start(): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* 创建连接
|
|
19
|
-
*/
|
|
20
|
-
link(): Promise<void>;
|
|
21
|
-
/**
|
|
22
|
-
* 接受消息
|
|
23
|
-
*/
|
|
24
|
-
message(str: string): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* 渲染标准方法
|
|
27
|
-
* @param options 渲染参数
|
|
28
|
-
*/
|
|
29
|
-
render<T extends KarinRenderType>(options: T): Promise<RenderResult<T>>;
|
|
30
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import axios from 'axios';
|
|
3
|
-
import WebSocket from 'ws';
|
|
4
|
-
import { render } from './app.js';
|
|
5
|
-
import { RenderBase } from './base.js';
|
|
6
|
-
import { createHash, randomUUID } from 'crypto';
|
|
7
|
-
import { listener } from '../core/index.js';
|
|
8
|
-
import { logger } from '../utils/index.js';
|
|
9
|
-
export class RenderClientEven extends RenderBase {
|
|
10
|
-
url;
|
|
11
|
-
type;
|
|
12
|
-
id;
|
|
13
|
-
index;
|
|
14
|
-
retry;
|
|
15
|
-
reg;
|
|
16
|
-
ws;
|
|
17
|
-
constructor(url) {
|
|
18
|
-
super();
|
|
19
|
-
this.url = url;
|
|
20
|
-
this.type = 'image';
|
|
21
|
-
this.id = 'puppeteer';
|
|
22
|
-
this.index = 0;
|
|
23
|
-
this.retry = 0;
|
|
24
|
-
this.reg = new RegExp(`(${process.cwd().replace(/\\/g, '\\\\')}|${process.cwd().replace(/\\/g, '/')})`, 'g');
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* 初始化
|
|
28
|
-
*/
|
|
29
|
-
async start() {
|
|
30
|
-
try {
|
|
31
|
-
const response = await axios.head(this.url);
|
|
32
|
-
if (response.status === 200) {
|
|
33
|
-
logger.mark(`[渲染器:${this.id}][WebSocket] 注册渲染器:${logger.green(this.url)}`);
|
|
34
|
-
try {
|
|
35
|
-
this.index = render.app({ id: this.id, type: this.type, render: this.render.bind(this) });
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
logger.error(`[渲染器:${this.id}] 注册渲染器失败:`, error);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
logger.error(`[渲染器:${this.id}] 注册渲染器失败:渲染器发生错误`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (error) {
|
|
46
|
-
logger.error(`[渲染器:${this.id}] 注册渲染器失败:`, error);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* 创建连接
|
|
51
|
-
*/
|
|
52
|
-
async link() {
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
55
|
-
return resolve();
|
|
56
|
-
}
|
|
57
|
-
/** 连接ws */
|
|
58
|
-
this.ws = new WebSocket(this.url);
|
|
59
|
-
/** 建立连接 */
|
|
60
|
-
this.ws.on('open', () => {
|
|
61
|
-
logger.mark(`[渲染器:${this.id}][WebSocket] 建立连接:${logger.green(this.url)}`);
|
|
62
|
-
/** 监听消息 */
|
|
63
|
-
this.ws.on('message', data => this.message(data.toString()));
|
|
64
|
-
resolve();
|
|
65
|
-
});
|
|
66
|
-
/** 监听断开 */
|
|
67
|
-
this.ws.once('close', async () => {
|
|
68
|
-
/** 停止监听 */
|
|
69
|
-
this.ws.removeAllListeners();
|
|
70
|
-
});
|
|
71
|
-
/** 监听错误 */
|
|
72
|
-
this.ws.on('error', async (e) => {
|
|
73
|
-
this.ws.close();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* 接受消息
|
|
79
|
-
*/
|
|
80
|
-
async message(str) {
|
|
81
|
-
const data = JSON.parse(str);
|
|
82
|
-
switch (data.action) {
|
|
83
|
-
/** 静态文件 */
|
|
84
|
-
case 'static': {
|
|
85
|
-
const filePath = decodeURIComponent(data.params.file);
|
|
86
|
-
logger.debug(`[渲染器:${this.id}][正向WS] 访问静态文件:${filePath}`);
|
|
87
|
-
const file = fs.readFileSync('.' + filePath);
|
|
88
|
-
const md5 = createHash('md5').update(file).digest('hex');
|
|
89
|
-
const params = data.params.md5?.includes(md5)
|
|
90
|
-
? { echo: data.echo, action: 'static', status: 'ok', data: { verifiedMd5: md5 } }
|
|
91
|
-
: { echo: data.echo, action: 'static', status: 'ok', data: { file } };
|
|
92
|
-
return this.ws.send(JSON.stringify(params));
|
|
93
|
-
}
|
|
94
|
-
/** 渲染结果 */
|
|
95
|
-
case 'renderRes': {
|
|
96
|
-
listener.emit(data.echo, data);
|
|
97
|
-
break;
|
|
98
|
-
}
|
|
99
|
-
/** 超时 */
|
|
100
|
-
case 'timeout': {
|
|
101
|
-
logger.debug(`[渲染器:${this.id}][正向WS] 处理超时`);
|
|
102
|
-
break;
|
|
103
|
-
}
|
|
104
|
-
/** 未知数据 */
|
|
105
|
-
default: {
|
|
106
|
-
logger.warn(`[渲染器:${this.id}] 收到未知数据:`, data);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* 渲染标准方法
|
|
112
|
-
* @param options 渲染参数
|
|
113
|
-
*/
|
|
114
|
-
async render(options) {
|
|
115
|
-
/** 渲染模板 */
|
|
116
|
-
let file = options.file;
|
|
117
|
-
let action = 'renderHtml';
|
|
118
|
-
if (options.file.includes('http') || options.vue) {
|
|
119
|
-
action = 'render';
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
file = this.dealTpl(options);
|
|
123
|
-
/** 判断是本地karin-puppeteer还是远程 */
|
|
124
|
-
if (!/127\.0\.0\.1|localhost/.test(this.url)) {
|
|
125
|
-
file = fs.readFileSync(file, 'utf-8').replace(this.reg, '');
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
action = 'render';
|
|
129
|
-
file = 'file://' + file;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
if (!file) {
|
|
133
|
-
logger.error(`[渲染器:${this.id}:${this.index}] 渲染文件不存在:${options.file}`);
|
|
134
|
-
return '';
|
|
135
|
-
}
|
|
136
|
-
/** 编码 */
|
|
137
|
-
file = encodeURIComponent(file);
|
|
138
|
-
const data = options;
|
|
139
|
-
const echo = randomUUID();
|
|
140
|
-
/** 移除掉模板参数 */
|
|
141
|
-
if (data.data)
|
|
142
|
-
delete data.data;
|
|
143
|
-
data.file = file;
|
|
144
|
-
const req = JSON.stringify({ echo, action, data });
|
|
145
|
-
logger.debug(`[渲染器:${this.id}:${this.index}][正向WS] 请求:${this.url} \nhtml: ${options.file} \ndata: ${JSON.stringify(data)}`);
|
|
146
|
-
await this.link();
|
|
147
|
-
this.ws.send(req);
|
|
148
|
-
return new Promise((resolve, reject) => {
|
|
149
|
-
listener.once(echo, (data) => {
|
|
150
|
-
if (data.ok)
|
|
151
|
-
return resolve(data.data);
|
|
152
|
-
reject(new Error(JSON.stringify(data)));
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|