@feng3d/ctc 0.0.10 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -32
- package/dist/admin-server.d.ts +65 -12
- package/dist/admin-server.d.ts.map +1 -1
- package/dist/admin-server.js +291 -564
- package/dist/admin-server.js.map +1 -1
- package/dist/cli.d.ts +12 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +931 -311
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +20 -11
- package/dist/config.js.map +1 -1
- package/dist/controller.d.ts +27 -124
- package/dist/controller.d.ts.map +1 -1
- package/dist/controller.js +77 -139
- package/dist/controller.js.map +1 -1
- package/dist/data-channel.d.ts +76 -0
- package/dist/data-channel.d.ts.map +1 -0
- package/dist/data-channel.js +222 -0
- package/dist/data-channel.js.map +1 -0
- package/dist/forward-proxy.d.ts +100 -0
- package/dist/forward-proxy.d.ts.map +1 -0
- package/dist/forward-proxy.js +407 -0
- package/dist/forward-proxy.js.map +1 -0
- package/dist/handlers/unified-handler.d.ts +33 -75
- package/dist/handlers/unified-handler.d.ts.map +1 -1
- package/dist/handlers/unified-handler.js +191 -315
- package/dist/handlers/unified-handler.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +135 -36
- package/dist/index.js.map +1 -1
- package/dist/ipc-handler.d.ts +52 -0
- package/dist/ipc-handler.d.ts.map +1 -0
- package/dist/ipc-handler.js +110 -0
- package/dist/ipc-handler.js.map +1 -0
- package/dist/proxy-manager.d.ts +13 -6
- package/dist/proxy-manager.d.ts.map +1 -1
- package/dist/proxy-manager.js +58 -23
- package/dist/proxy-manager.js.map +1 -1
- package/package.json +9 -5
package/dist/index.js
CHANGED
|
@@ -11,7 +11,28 @@ import { Config } from './config.js';
|
|
|
11
11
|
import { Controller } from './controller.js';
|
|
12
12
|
import { ProxyManager } from './proxy-manager.js';
|
|
13
13
|
import { AdminServer } from './admin-server.js';
|
|
14
|
+
import { IpcHandler } from './ipc-handler.js';
|
|
14
15
|
import { logger } from '@feng3d/chuantou-shared';
|
|
16
|
+
import { join } from 'path';
|
|
17
|
+
import { homedir } from 'os';
|
|
18
|
+
import { ForwardProxy } from './forward-proxy.js';
|
|
19
|
+
import { writeFile } from 'fs';
|
|
20
|
+
/**
|
|
21
|
+
* 更新配置文件中的代理列表
|
|
22
|
+
*/
|
|
23
|
+
async function updateConfigProxies(proxies) {
|
|
24
|
+
const config = await Config.load();
|
|
25
|
+
config.proxies = proxies;
|
|
26
|
+
const configPath = join(homedir(), '.chuantou', 'client', 'config.json');
|
|
27
|
+
writeFile(configPath, JSON.stringify(config, null, 2), 'utf-8', (err) => {
|
|
28
|
+
if (err) {
|
|
29
|
+
logger.error('更新配置文件失败:', err);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
logger.log('配置文件已更新');
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
15
36
|
/**
|
|
16
37
|
* 导出核心类和类型,供作为库使用时引用。
|
|
17
38
|
*/
|
|
@@ -20,6 +41,8 @@ export { Controller } from './controller.js';
|
|
|
20
41
|
export { ProxyManager } from './proxy-manager.js';
|
|
21
42
|
export { AdminServer } from './admin-server.js';
|
|
22
43
|
export { UnifiedHandler } from './handlers/unified-handler.js';
|
|
44
|
+
export { IpcHandler } from './ipc-handler.js';
|
|
45
|
+
export { ForwardProxy } from './forward-proxy.js';
|
|
23
46
|
/**
|
|
24
47
|
* 客户端主入口函数(独立运行模式)。
|
|
25
48
|
*
|
|
@@ -51,35 +74,95 @@ async function main() {
|
|
|
51
74
|
const controller = new Controller(config);
|
|
52
75
|
// 创建代理管理器
|
|
53
76
|
const proxyManager = new ProxyManager(controller);
|
|
77
|
+
// 创建正向穿透代理
|
|
78
|
+
const forwardProxy = new ForwardProxy(controller);
|
|
54
79
|
// 已注册的代理配置列表(用于管理页面)
|
|
55
80
|
const registeredProxies = [];
|
|
81
|
+
let nextProxyIndex = 1;
|
|
56
82
|
for (const p of config.proxies) {
|
|
57
|
-
registeredProxies.push({ ...p });
|
|
83
|
+
registeredProxies.push({ ...p, index: nextProxyIndex++ });
|
|
58
84
|
}
|
|
59
85
|
// 创建管理页面服务器
|
|
60
|
-
const
|
|
86
|
+
const adminServerConfig = { port: config.adminPort, host: '127.0.0.1' };
|
|
61
87
|
// 获取状态回调
|
|
62
|
-
() =>
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
88
|
+
const getStatusCallback = () => {
|
|
89
|
+
// 获取实际在 ProxyManager 中注册的端口
|
|
90
|
+
const actualRegisteredPorts = proxyManager.getRegisteredPorts();
|
|
91
|
+
// 返回所有配置的代理(去重),并标记注册状态
|
|
92
|
+
const actualRegisteredProxies = registeredProxies
|
|
93
|
+
.filter((p, index, self) => {
|
|
94
|
+
// 去重:只保留第一次出现的端口
|
|
95
|
+
return index === self.findIndex(other => other.remotePort === p.remotePort);
|
|
96
|
+
})
|
|
97
|
+
.map(p => ({ ...p, registered: actualRegisteredPorts.includes(p.remotePort) }));
|
|
98
|
+
const status = {
|
|
99
|
+
running: true,
|
|
100
|
+
serverUrl: config.serverUrl,
|
|
101
|
+
connected: controller.isConnected(),
|
|
102
|
+
authenticated: controller.isAuthenticated(),
|
|
103
|
+
uptime: Date.now() - startTime,
|
|
104
|
+
proxies: actualRegisteredProxies,
|
|
105
|
+
reconnectAttempts: controller.getReconnectAttempts(),
|
|
106
|
+
};
|
|
107
|
+
// 添加正向穿透相关信息
|
|
108
|
+
try {
|
|
109
|
+
const forwardProxies = forwardProxy.getProxies();
|
|
110
|
+
status.forwardProxies = forwardProxies;
|
|
111
|
+
status.isRegistered = true; // 假设已注册(实际应从 Controller 获取)
|
|
112
|
+
status.clientId = controller.getClientId();
|
|
113
|
+
}
|
|
114
|
+
catch (e) {
|
|
115
|
+
// 如果获取失败,返回基础状态
|
|
116
|
+
}
|
|
117
|
+
return status;
|
|
118
|
+
};
|
|
71
119
|
// 添加代理回调
|
|
72
|
-
async (proxy) => {
|
|
120
|
+
const addProxyCallback = async (proxy) => {
|
|
73
121
|
await proxyManager.registerProxy(proxy);
|
|
74
|
-
registeredProxies.push({ ...proxy });
|
|
75
|
-
|
|
122
|
+
registeredProxies.push({ ...proxy, index: nextProxyIndex++ });
|
|
123
|
+
// 同步更新配置文件
|
|
124
|
+
await updateConfigProxies(registeredProxies.map(p => ({ remotePort: p.remotePort, localPort: p.localPort, localHost: p.localHost })));
|
|
125
|
+
};
|
|
76
126
|
// 删除代理回调
|
|
77
|
-
async (remotePort) => {
|
|
127
|
+
const removeProxyCallback = async (remotePort) => {
|
|
78
128
|
await proxyManager.unregisterProxy(remotePort);
|
|
79
129
|
const index = registeredProxies.findIndex(p => p.remotePort === remotePort);
|
|
80
130
|
if (index !== -1) {
|
|
81
131
|
registeredProxies.splice(index, 1);
|
|
82
132
|
}
|
|
133
|
+
// 同步更新配置文件
|
|
134
|
+
await updateConfigProxies(registeredProxies);
|
|
135
|
+
};
|
|
136
|
+
// 添加正向穿透回调
|
|
137
|
+
const addForwardProxyCallback = async (entry) => {
|
|
138
|
+
await forwardProxy.addProxy(entry);
|
|
139
|
+
};
|
|
140
|
+
// 删除正向穿透回调
|
|
141
|
+
const removeForwardProxyCallback = async (localPort) => {
|
|
142
|
+
await forwardProxy.removeProxy(localPort);
|
|
143
|
+
};
|
|
144
|
+
// 注册客户端回调
|
|
145
|
+
const registerClientCallback = async (description) => {
|
|
146
|
+
return await forwardProxy.registerAsClient(description);
|
|
147
|
+
};
|
|
148
|
+
// 获取客户端列表回调
|
|
149
|
+
const getClientListCallback = async () => {
|
|
150
|
+
return await forwardProxy.getClientList();
|
|
151
|
+
};
|
|
152
|
+
// 重连回调
|
|
153
|
+
const reconnectCallback = async () => {
|
|
154
|
+
logger.log('收到手动重连请求');
|
|
155
|
+
// 先断开现有连接
|
|
156
|
+
controller.disconnect();
|
|
157
|
+
// 然后重新连接
|
|
158
|
+
await controller.connect();
|
|
159
|
+
};
|
|
160
|
+
// 创建管理页面服务器
|
|
161
|
+
const adminServer = new AdminServer(adminServerConfig, getStatusCallback, addProxyCallback, removeProxyCallback, addForwardProxyCallback, removeForwardProxyCallback, registerClientCallback, getClientListCallback, undefined, // sendMessage 会在后面设置
|
|
162
|
+
reconnectCallback);
|
|
163
|
+
// 设置发送消息回调(用于正向穿透向服务端发送消息)
|
|
164
|
+
adminServer.setSendMessageCallback(async (message) => {
|
|
165
|
+
return await controller.sendRequest(message);
|
|
83
166
|
});
|
|
84
167
|
// 监听控制器事件
|
|
85
168
|
controller.on('connected', () => {
|
|
@@ -90,31 +173,41 @@ async function main() {
|
|
|
90
173
|
});
|
|
91
174
|
controller.on('authenticated', async () => {
|
|
92
175
|
logger.log('已认证,正在注册代理...');
|
|
93
|
-
//
|
|
176
|
+
// 获取实际在 ProxyManager 中注册的端口
|
|
177
|
+
const actualRegisteredPorts = proxyManager.getRegisteredPorts();
|
|
178
|
+
// 注册所有代理(只注册尚未实际注册的)
|
|
94
179
|
for (const proxyConfig of config.proxies) {
|
|
180
|
+
if (actualRegisteredPorts.includes(proxyConfig.remotePort)) {
|
|
181
|
+
logger.log(`代理 :${proxyConfig.remotePort} 已注册,跳过`);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
95
184
|
try {
|
|
96
185
|
await proxyManager.registerProxy(proxyConfig);
|
|
97
|
-
// 代理配置已在初始化时添加到 registeredProxies
|
|
98
186
|
}
|
|
99
187
|
catch (error) {
|
|
100
188
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
101
189
|
logger.error(`注册代理失败: ${errorMessage}`);
|
|
102
190
|
}
|
|
103
191
|
}
|
|
104
|
-
// 启动管理页面服务器
|
|
105
|
-
try {
|
|
106
|
-
await adminServer.start();
|
|
107
|
-
}
|
|
108
|
-
catch (error) {
|
|
109
|
-
logger.error('管理页面启动失败:', error);
|
|
110
|
-
}
|
|
111
192
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
193
|
+
// 设置 IPC 请求监听(用于处理 CLI 添加代理的请求)
|
|
194
|
+
const ipcHandler = new IpcHandler({
|
|
195
|
+
requestDir: join(homedir(), '.chuantou', 'proxy-requests'),
|
|
196
|
+
controller,
|
|
197
|
+
proxyManager,
|
|
198
|
+
registeredProxies,
|
|
115
199
|
});
|
|
200
|
+
ipcHandler.start();
|
|
201
|
+
// 启动管理页面服务器(立即启动,不等待认证)
|
|
202
|
+
try {
|
|
203
|
+
await adminServer.start();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
logger.error('管理页面启动失败:', error);
|
|
207
|
+
}
|
|
116
208
|
// 优雅关闭
|
|
117
209
|
const shutdown = async () => {
|
|
210
|
+
ipcHandler.stop();
|
|
118
211
|
logger.log('\n正在关闭...');
|
|
119
212
|
await adminServer.stop();
|
|
120
213
|
await proxyManager.destroy();
|
|
@@ -123,21 +216,27 @@ async function main() {
|
|
|
123
216
|
};
|
|
124
217
|
process.on('SIGINT', shutdown);
|
|
125
218
|
process.on('SIGTERM', shutdown);
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
catch (error) {
|
|
131
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
132
|
-
logger.error('连接服务器失败:', errorMessage);
|
|
219
|
+
// 未捕获异常处理 - 崩溃时记录退出码
|
|
220
|
+
process.on('uncaughtException', (error) => {
|
|
221
|
+
logger.error('未捕获异常:', error);
|
|
222
|
+
// 写入非零退出码,让父进程知道是异常退出
|
|
133
223
|
process.exit(1);
|
|
134
|
-
}
|
|
224
|
+
});
|
|
225
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
226
|
+
logger.error('未处理的 Promise 拒绝:', reason);
|
|
227
|
+
// 写入非零退出码
|
|
228
|
+
process.exit(1);
|
|
229
|
+
});
|
|
230
|
+
// 连接到服务器(不会抛出连接失败的异常,会自动重连)
|
|
231
|
+
await controller.connect();
|
|
135
232
|
}
|
|
136
233
|
// 检查是否作为主模块运行
|
|
137
|
-
|
|
234
|
+
// 使用更简单的方式:通过检查是否直接运行此文件
|
|
235
|
+
const isMainModule = process.argv[1] && process.argv[1].endsWith('index.js');
|
|
138
236
|
if (isMainModule) {
|
|
139
237
|
main().catch((error) => {
|
|
140
238
|
logger.error('启动客户端失败:', error);
|
|
239
|
+
// 注意:main() 内部已经处理了资源清理
|
|
141
240
|
process.exit(1);
|
|
142
241
|
});
|
|
143
242
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAgB,MAAM,mBAAmB,CAAC;AAC9D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ipc-handler
|
|
3
|
+
*
|
|
4
|
+
* IPC 请求处理模块。
|
|
5
|
+
*
|
|
6
|
+
* 通过文件系统实现进程间通信(IPC),允许 CLI 向运行中的客户端进程
|
|
7
|
+
* 发送添加代理请求。请求通过 JSON 文件传递,响应通过 .resp 文件返回。
|
|
8
|
+
*/
|
|
9
|
+
import { ProxyConfig } from '@feng3d/chuantou-shared';
|
|
10
|
+
import { Controller } from './controller.js';
|
|
11
|
+
import { ProxyManager } from './proxy-manager.js';
|
|
12
|
+
/**
|
|
13
|
+
* IPC 请求处理器,处理来自 CLI 的文件系统 IPC 请求。
|
|
14
|
+
*
|
|
15
|
+
* 通过定时扫描请求目录,发现新的请求文件后处理并写入响应文件。
|
|
16
|
+
* 使用 processingFiles 集合防止同一请求被重复处理。
|
|
17
|
+
*/
|
|
18
|
+
export declare class IpcHandler {
|
|
19
|
+
private processingFiles;
|
|
20
|
+
private requestDir;
|
|
21
|
+
private controller;
|
|
22
|
+
private proxyManager;
|
|
23
|
+
private registeredProxies;
|
|
24
|
+
private timer;
|
|
25
|
+
constructor(options: {
|
|
26
|
+
requestDir: string;
|
|
27
|
+
controller: Controller;
|
|
28
|
+
proxyManager: ProxyManager;
|
|
29
|
+
registeredProxies: ProxyConfig[];
|
|
30
|
+
});
|
|
31
|
+
/**
|
|
32
|
+
* 启动 IPC 请求监听,每 500ms 扫描一次请求目录。
|
|
33
|
+
*/
|
|
34
|
+
start(): void;
|
|
35
|
+
/**
|
|
36
|
+
* 停止 IPC 请求监听。
|
|
37
|
+
*/
|
|
38
|
+
stop(): void;
|
|
39
|
+
/**
|
|
40
|
+
* 扫描请求目录,处理新的请求文件。
|
|
41
|
+
* 已在处理中的文件会被跳过,防止重复处理。
|
|
42
|
+
*/
|
|
43
|
+
checkRequests(): void;
|
|
44
|
+
/**
|
|
45
|
+
* 处理单个添加代理请求文件。
|
|
46
|
+
*
|
|
47
|
+
* 读取请求文件 → 检查认证状态 → 注册代理 → 写入响应文件。
|
|
48
|
+
* 无论成功或失败,始终写入响应文件,确保 CLI 不会超时等待。
|
|
49
|
+
*/
|
|
50
|
+
handleRequest(requestFilePath: string): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=ipc-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-handler.d.ts","sourceRoot":"","sources":["../src/ipc-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,WAAW,EAAU,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,KAAK,CAA+B;gBAEhC,OAAO,EAAE;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,UAAU,CAAC;QACvB,YAAY,EAAE,YAAY,CAAC;QAC3B,iBAAiB,EAAE,WAAW,EAAE,CAAC;KAClC;IAOD;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;;OAGG;IACH,aAAa,IAAI,IAAI;IAiBrB;;;;;OAKG;IACG,aAAa,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAwC5D"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ipc-handler
|
|
3
|
+
*
|
|
4
|
+
* IPC 请求处理模块。
|
|
5
|
+
*
|
|
6
|
+
* 通过文件系统实现进程间通信(IPC),允许 CLI 向运行中的客户端进程
|
|
7
|
+
* 发送添加代理请求。请求通过 JSON 文件传递,响应通过 .resp 文件返回。
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { logger } from '@feng3d/chuantou-shared';
|
|
12
|
+
/**
|
|
13
|
+
* IPC 请求处理器,处理来自 CLI 的文件系统 IPC 请求。
|
|
14
|
+
*
|
|
15
|
+
* 通过定时扫描请求目录,发现新的请求文件后处理并写入响应文件。
|
|
16
|
+
* 使用 processingFiles 集合防止同一请求被重复处理。
|
|
17
|
+
*/
|
|
18
|
+
export class IpcHandler {
|
|
19
|
+
constructor(options) {
|
|
20
|
+
this.processingFiles = new Set();
|
|
21
|
+
this.timer = null;
|
|
22
|
+
this.requestDir = options.requestDir;
|
|
23
|
+
this.controller = options.controller;
|
|
24
|
+
this.proxyManager = options.proxyManager;
|
|
25
|
+
this.registeredProxies = options.registeredProxies;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 启动 IPC 请求监听,每 500ms 扫描一次请求目录。
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
mkdirSync(this.requestDir, { recursive: true });
|
|
32
|
+
this.timer = setInterval(() => this.checkRequests(), 500);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 停止 IPC 请求监听。
|
|
36
|
+
*/
|
|
37
|
+
stop() {
|
|
38
|
+
if (this.timer) {
|
|
39
|
+
clearInterval(this.timer);
|
|
40
|
+
this.timer = null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* 扫描请求目录,处理新的请求文件。
|
|
45
|
+
* 已在处理中的文件会被跳过,防止重复处理。
|
|
46
|
+
*/
|
|
47
|
+
checkRequests() {
|
|
48
|
+
try {
|
|
49
|
+
const files = readdirSync(this.requestDir);
|
|
50
|
+
for (const file of files) {
|
|
51
|
+
if (file.endsWith('.json') && !this.processingFiles.has(file)) {
|
|
52
|
+
this.processingFiles.add(file);
|
|
53
|
+
const requestPath = join(this.requestDir, file);
|
|
54
|
+
this.handleRequest(requestPath).finally(() => {
|
|
55
|
+
this.processingFiles.delete(file);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// 忽略目录读取错误
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 处理单个添加代理请求文件。
|
|
66
|
+
*
|
|
67
|
+
* 读取请求文件 → 检查认证状态 → 注册代理 → 写入响应文件。
|
|
68
|
+
* 无论成功或失败,始终写入响应文件,确保 CLI 不会超时等待。
|
|
69
|
+
*/
|
|
70
|
+
async handleRequest(requestFilePath) {
|
|
71
|
+
const responsePath = requestFilePath.replace('.json', '.resp');
|
|
72
|
+
try {
|
|
73
|
+
const requestData = JSON.parse(readFileSync(requestFilePath, 'utf-8'));
|
|
74
|
+
if (requestData.type !== 'add-proxy')
|
|
75
|
+
return;
|
|
76
|
+
const proxy = requestData.proxy;
|
|
77
|
+
logger.log(`收到添加代理请求: :${proxy.remotePort} -> ${proxy.localHost || 'localhost'}:${proxy.localPort}`);
|
|
78
|
+
// 检查控制器是否已认证
|
|
79
|
+
if (!this.controller.isAuthenticated()) {
|
|
80
|
+
writeFileSync(responsePath, JSON.stringify({ success: false, error: '客户端未连接到服务器,请稍后重试' }));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
await this.proxyManager.registerProxy(proxy);
|
|
85
|
+
this.registeredProxies.push({ ...proxy });
|
|
86
|
+
// 写入成功响应
|
|
87
|
+
writeFileSync(responsePath, JSON.stringify({ success: true }));
|
|
88
|
+
logger.log(`代理已通过 IPC 添加: :${proxy.remotePort}`);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
92
|
+
logger.error(`通过 IPC 添加代理失败: ${errorMessage}`);
|
|
93
|
+
// 写入失败响应
|
|
94
|
+
writeFileSync(responsePath, JSON.stringify({ success: false, error: errorMessage }));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
logger.error('处理添加代理请求时出错:', error);
|
|
99
|
+
// 确保即使在外层异常时也写入响应文件,避免 CLI 超时
|
|
100
|
+
try {
|
|
101
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
102
|
+
writeFileSync(responsePath, JSON.stringify({ success: false, error: errorMessage }));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// 无法写入响应文件 - 忽略
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=ipc-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-handler.js","sourceRoot":"","sources":["../src/ipc-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAe,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAI9D;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IAQrB,YAAY,OAKX;QAZO,oBAAe,GAAG,IAAI,GAAG,EAAU,CAAC;QAKpC,UAAK,GAA0B,IAAI,CAAC;QAQ1C,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,KAAK;QACH,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,aAAa;QACX,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;oBAChD,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;wBAC3C,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACpC,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,WAAW;QACb,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,eAAuB;QACzC,MAAM,YAAY,GAAG,eAAe,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;YACvE,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO;YAE7C,MAAM,KAAK,GAAgB,WAAW,CAAC,KAAK,CAAC;YAE7C,MAAM,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,UAAU,OAAO,KAAK,CAAC,SAAS,IAAI,WAAW,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YAErG,aAAa;YACb,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,EAAE,CAAC;gBACvC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;gBAC3F,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;gBAC7C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;gBAE1C,SAAS;gBACT,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC/D,MAAM,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACnD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,MAAM,CAAC,KAAK,CAAC,kBAAkB,YAAY,EAAE,CAAC,CAAC;gBAC/C,SAAS;gBACT,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YACvF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;YACpC,8BAA8B;YAC9B,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC5E,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;YACvF,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
package/dist/proxy-manager.d.ts
CHANGED
|
@@ -7,21 +7,23 @@
|
|
|
7
7
|
* 创建统一的处理器(同时支持 HTTP 和 WebSocket)、
|
|
8
8
|
* 以及在连接断开时清理所有处理器。
|
|
9
9
|
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
10
11
|
import { Controller } from './controller.js';
|
|
11
12
|
import { ProxyConfig } from '@feng3d/chuantou-shared';
|
|
12
13
|
/**
|
|
13
14
|
* 代理管理器类,负责管理所有代理隧道的注册、注销和生命周期。
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
+
* 使用 UnifiedHandler 处理所有协议(HTTP、WebSocket、TCP)。
|
|
16
17
|
* 当控制器连接断开时,自动清理所有处理器。
|
|
17
18
|
*
|
|
18
19
|
* @example
|
|
19
20
|
* ```typescript
|
|
20
21
|
* const proxyManager = new ProxyManager(controller);
|
|
21
22
|
* await proxyManager.registerProxy({ remotePort: 8080, localPort: 3000 });
|
|
23
|
+
* await proxyManager.registerProxy({ remotePort: 2222, localPort: 22 });
|
|
22
24
|
* ```
|
|
23
25
|
*/
|
|
24
|
-
export declare class ProxyManager {
|
|
26
|
+
export declare class ProxyManager extends EventEmitter {
|
|
25
27
|
/** 控制器实例,用于与服务器通信 */
|
|
26
28
|
private controller;
|
|
27
29
|
/** 代理处理器映射表,键为远程端口号,值为对应的处理器实例 */
|
|
@@ -35,9 +37,8 @@ export declare class ProxyManager {
|
|
|
35
37
|
/**
|
|
36
38
|
* 向服务器注册一个代理隧道。
|
|
37
39
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* 每个端口同时支持 HTTP 和 WebSocket 协议。
|
|
40
|
+
* 发送注册消息到服务器,注册成功后创建 UnifiedHandler(同时支持 HTTP、WebSocket 和 TCP)。
|
|
41
|
+
* 如果未连接到服务器,仅添加到本地列表,待连接后自动注册。
|
|
41
42
|
*
|
|
42
43
|
* @param config - 代理配置对象,包含远程端口、本地端口等信息
|
|
43
44
|
* @throws {Error} 注册失败时抛出错误,包含服务器返回的错误信息
|
|
@@ -46,7 +47,7 @@ export declare class ProxyManager {
|
|
|
46
47
|
/**
|
|
47
48
|
* 注销指定远程端口的代理隧道。
|
|
48
49
|
*
|
|
49
|
-
*
|
|
50
|
+
* 销毁对应的处理器,并向服务器发送注销请求(仅在已连接时)。
|
|
50
51
|
*
|
|
51
52
|
* @param remotePort - 要注销的代理对应的远程端口号
|
|
52
53
|
*/
|
|
@@ -65,6 +66,12 @@ export declare class ProxyManager {
|
|
|
65
66
|
* 销毁所有处理器并清空处理器映射表。
|
|
66
67
|
*/
|
|
67
68
|
private onDisconnected;
|
|
69
|
+
/**
|
|
70
|
+
* 获取所有已注册的远程端口列表
|
|
71
|
+
*
|
|
72
|
+
* @returns 已注册的远程端口号数组
|
|
73
|
+
*/
|
|
74
|
+
getRegisteredPorts(): number[];
|
|
68
75
|
/**
|
|
69
76
|
* 销毁代理管理器,注销所有代理并释放资源。
|
|
70
77
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../src/proxy-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAU,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"proxy-manager.d.ts","sourceRoot":"","sources":["../src/proxy-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAU,MAAM,yBAAyB,CAAC;AAW9D;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,qBAAqB;IACrB,OAAO,CAAC,UAAU,CAAa;IAE/B,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAA2B;IAE3C;;;;OAIG;gBACS,UAAU,EAAE,UAAU;IAWlC;;;;;;;;OAQG;IACG,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAuCvD;;;;;;OAMG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BxD;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;OAIG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}
|
package/dist/proxy-manager.js
CHANGED
|
@@ -7,28 +7,31 @@
|
|
|
7
7
|
* 创建统一的处理器(同时支持 HTTP 和 WebSocket)、
|
|
8
8
|
* 以及在连接断开时清理所有处理器。
|
|
9
9
|
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
10
11
|
import { logger } from '@feng3d/chuantou-shared';
|
|
11
12
|
import { UnifiedHandler } from './handlers/unified-handler.js';
|
|
12
13
|
import { MessageType, createMessage } from '@feng3d/chuantou-shared';
|
|
13
14
|
/**
|
|
14
15
|
* 代理管理器类,负责管理所有代理隧道的注册、注销和生命周期。
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
+
* 使用 UnifiedHandler 处理所有协议(HTTP、WebSocket、TCP)。
|
|
17
18
|
* 当控制器连接断开时,自动清理所有处理器。
|
|
18
19
|
*
|
|
19
20
|
* @example
|
|
20
21
|
* ```typescript
|
|
21
22
|
* const proxyManager = new ProxyManager(controller);
|
|
22
23
|
* await proxyManager.registerProxy({ remotePort: 8080, localPort: 3000 });
|
|
24
|
+
* await proxyManager.registerProxy({ remotePort: 2222, localPort: 22 });
|
|
23
25
|
* ```
|
|
24
26
|
*/
|
|
25
|
-
export class ProxyManager {
|
|
27
|
+
export class ProxyManager extends EventEmitter {
|
|
26
28
|
/**
|
|
27
29
|
* 创建代理管理器实例。
|
|
28
30
|
*
|
|
29
31
|
* @param controller - 控制器实例,用于与服务器进行通信
|
|
30
32
|
*/
|
|
31
33
|
constructor(controller) {
|
|
34
|
+
super();
|
|
32
35
|
this.controller = controller;
|
|
33
36
|
this.handlers = new Map();
|
|
34
37
|
// 监听控制器事件
|
|
@@ -39,38 +42,49 @@ export class ProxyManager {
|
|
|
39
42
|
/**
|
|
40
43
|
* 向服务器注册一个代理隧道。
|
|
41
44
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* 每个端口同时支持 HTTP 和 WebSocket 协议。
|
|
45
|
+
* 发送注册消息到服务器,注册成功后创建 UnifiedHandler(同时支持 HTTP、WebSocket 和 TCP)。
|
|
46
|
+
* 如果未连接到服务器,仅添加到本地列表,待连接后自动注册。
|
|
45
47
|
*
|
|
46
48
|
* @param config - 代理配置对象,包含远程端口、本地端口等信息
|
|
47
49
|
* @throws {Error} 注册失败时抛出错误,包含服务器返回的错误信息
|
|
48
50
|
*/
|
|
49
51
|
async registerProxy(config) {
|
|
50
52
|
logger.log(`正在注册代理: :${config.remotePort} -> ${config.localHost || 'localhost'}:${config.localPort}`);
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
53
|
+
// 只有在已认证的情况下才向服务器注册
|
|
54
|
+
if (this.controller.isAuthenticated()) {
|
|
55
|
+
const registerMsg = createMessage(MessageType.REGISTER, {
|
|
56
|
+
remotePort: config.remotePort,
|
|
57
|
+
localPort: config.localPort,
|
|
58
|
+
localHost: config.localHost,
|
|
59
|
+
});
|
|
60
|
+
try {
|
|
61
|
+
const response = await this.controller.sendRequest(registerMsg);
|
|
62
|
+
if (!response.payload.success) {
|
|
63
|
+
throw new Error(`注册代理失败: ${response.payload.error}`);
|
|
64
|
+
}
|
|
65
|
+
logger.log(`代理已注册: ${response.payload.remoteUrl}`);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// 服务器注册失败,抛出错误
|
|
69
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
70
|
+
throw new Error(`注册代理失败: ${errorMessage}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
logger.log(`代理已添加到本地列表: :${config.remotePort} -> ${config.localHost || 'localhost'}:${config.localPort} (待连接后自动注册)`);
|
|
60
75
|
}
|
|
61
|
-
|
|
62
|
-
// 创建统一的处理器(同时支持 HTTP 和 WebSocket)
|
|
76
|
+
// 无论是否连接成功,都创建本地处理器
|
|
63
77
|
const handler = new UnifiedHandler(this.controller, config);
|
|
64
|
-
// 设置处理器事件
|
|
65
78
|
handler.on('error', (error) => {
|
|
66
79
|
logger.error(`端口 ${config.remotePort} 的处理器错误:`, error);
|
|
67
80
|
});
|
|
68
81
|
this.handlers.set(config.remotePort, handler);
|
|
82
|
+
this.emit('handlerCreated', config.remotePort);
|
|
69
83
|
}
|
|
70
84
|
/**
|
|
71
85
|
* 注销指定远程端口的代理隧道。
|
|
72
86
|
*
|
|
73
|
-
*
|
|
87
|
+
* 销毁对应的处理器,并向服务器发送注销请求(仅在已连接时)。
|
|
74
88
|
*
|
|
75
89
|
* @param remotePort - 要注销的代理对应的远程端口号
|
|
76
90
|
*/
|
|
@@ -80,11 +94,24 @@ export class ProxyManager {
|
|
|
80
94
|
handler.destroy();
|
|
81
95
|
this.handlers.delete(remotePort);
|
|
82
96
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
97
|
+
// 只有在已连接的情况下才向服务器发送注销请求
|
|
98
|
+
if (this.controller.isConnected()) {
|
|
99
|
+
const unregisterMsg = createMessage(MessageType.UNREGISTER, {
|
|
100
|
+
remotePort,
|
|
101
|
+
});
|
|
102
|
+
try {
|
|
103
|
+
await this.controller.sendRequest(unregisterMsg);
|
|
104
|
+
logger.log(`代理已注销: 端口 ${remotePort}`);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// 即使服务器注销失败,本地也已经删除了,记录错误但不抛出
|
|
108
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
109
|
+
logger.error(`服务器注销代理失败: ${errorMessage}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
logger.log(`代理已移除: 端口 ${remotePort} (未连接到服务器)`);
|
|
114
|
+
}
|
|
88
115
|
}
|
|
89
116
|
/**
|
|
90
117
|
* 注销所有已注册的代理隧道。
|
|
@@ -112,6 +139,14 @@ export class ProxyManager {
|
|
|
112
139
|
}
|
|
113
140
|
this.handlers.clear();
|
|
114
141
|
}
|
|
142
|
+
/**
|
|
143
|
+
* 获取所有已注册的远程端口列表
|
|
144
|
+
*
|
|
145
|
+
* @returns 已注册的远程端口号数组
|
|
146
|
+
*/
|
|
147
|
+
getRegisteredPorts() {
|
|
148
|
+
return Array.from(this.handlers.keys());
|
|
149
|
+
}
|
|
115
150
|
/**
|
|
116
151
|
* 销毁代理管理器,注销所有代理并释放资源。
|
|
117
152
|
*
|