@feng3d/ctc 0.0.6

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.
@@ -0,0 +1,373 @@
1
+ /**
2
+ * @module handlers/unified-handler
3
+ *
4
+ * 统一代理连接处理器模块。
5
+ *
6
+ * 负责处理通过穿透隧道传输的 HTTP 和 WebSocket 连接。
7
+ * 同时支持 HTTP 请求转发和 WebSocket 连接桥接,无需区分协议类型。
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import { WebSocket } from 'ws';
11
+ import { request as httpRequest } from 'http';
12
+ import { request as httpsRequest } from 'https';
13
+ import { URL } from 'url';
14
+ import { logger } from '@feng3d/chuantou-shared';
15
+ import { MessageType, createMessage, } from '@feng3d/chuantou-shared';
16
+ /**
17
+ * 统一代理连接处理器类。
18
+ *
19
+ * 继承自 {@link EventEmitter},负责在远程客户端和本地服务之间建立双向数据转发通道。
20
+ * 同时支持 HTTP 请求转发和 WebSocket 连接桥接。
21
+ *
22
+ * 工作流程:
23
+ * 1. 监听控制器的 `newConnection` 事件,接收新的连接请求
24
+ * 2. 根据协议类型(http/websocket)建立相应的本地连接
25
+ * 3. 将本地服务发送的数据转发给服务器
26
+ * 4. 将服务器转发的远程客户端数据转发到本地服务
27
+ * 5. 处理连接关闭和错误情况
28
+ *
29
+ * 触发的事件:
30
+ * - `error` - 处理连接时发生错误
31
+ */
32
+ export class UnifiedHandler extends EventEmitter {
33
+ /**
34
+ * 创建统一处理器实例。
35
+ *
36
+ * 自动监听控制器的 `newConnection` 和 `connectionClose` 事件,
37
+ * 并设置数据转发监听器。
38
+ *
39
+ * @param controller - 控制器实例,用于与服务器通信
40
+ * @param config - 代理配置对象,包含本地服务地址和端口
41
+ */
42
+ constructor(controller, config) {
43
+ super();
44
+ /** 正在处理的 HTTP 连接映射表 */
45
+ this.pendingConnections = new Map();
46
+ /** 本地 WebSocket 连接映射表 */
47
+ this.localWsConnections = new Map();
48
+ /** 流式 HTTP 响应映射表(如 SSE) */
49
+ this.streamingResponses = new Map();
50
+ this.controller = controller;
51
+ this.config = config;
52
+ // 监听新连接事件
53
+ this.controller.on('newConnection', (msg) => {
54
+ if (msg.payload.protocol === 'http') {
55
+ this.handleHttpConnection(msg);
56
+ }
57
+ else if (msg.payload.protocol === 'websocket') {
58
+ this.handleWebSocketConnection(msg);
59
+ }
60
+ });
61
+ // 监听来自服务器的数据消息
62
+ this.setupDataListener();
63
+ // 监听连接关闭事件
64
+ this.controller.on('connectionClose', (msg) => {
65
+ this.handleConnectionClose(msg);
66
+ });
67
+ }
68
+ /**
69
+ * 设置从服务器接收数据的监听器。
70
+ */
71
+ setupDataListener() {
72
+ const controller = this.controller;
73
+ if (controller.ws) {
74
+ controller.ws.on('message', (data) => {
75
+ try {
76
+ const msg = JSON.parse(data.toString());
77
+ if (msg.type === 'connection_data') {
78
+ this.handleClientData(msg.connectionId, msg.data);
79
+ }
80
+ }
81
+ catch {
82
+ // 忽略解析错误
83
+ }
84
+ });
85
+ }
86
+ }
87
+ /**
88
+ * 处理来自服务器的新 HTTP 连接请求。
89
+ */
90
+ async handleHttpConnection(msg) {
91
+ const { connectionId, method, url, headers, body } = msg.payload;
92
+ logger.log(`HTTP 请求: ${method} ${url} (${connectionId})`);
93
+ // 构建本地 URL
94
+ const localUrl = `http://${this.config.localHost || 'localhost'}:${this.config.localPort}${url}`;
95
+ const parsedUrl = new URL(localUrl);
96
+ // 准备请求选项
97
+ const options = {
98
+ method,
99
+ hostname: parsedUrl.hostname,
100
+ port: parsedUrl.port || this.config.localPort,
101
+ path: parsedUrl.pathname + parsedUrl.search,
102
+ headers: this.filterHeaders(headers),
103
+ rejectUnauthorized: false,
104
+ };
105
+ // 创建请求
106
+ const requestFn = parsedUrl.protocol === 'https:' ? httpsRequest : httpRequest;
107
+ try {
108
+ const req = requestFn(options, (res) => {
109
+ const contentType = (res.headers['content-type'] || '').toLowerCase();
110
+ const isSSE = contentType.includes('text/event-stream');
111
+ if (isSSE) {
112
+ // SSE 流式转发 - 先发送响应头
113
+ logger.log(`SSE 流: ${url} (${connectionId})`);
114
+ this.sendResponseHeaders(connectionId, {
115
+ statusCode: res.statusCode || 200,
116
+ headers: res.headers,
117
+ });
118
+ this.streamingResponses.set(connectionId, res);
119
+ res.on('data', (chunk) => {
120
+ this.forwardStreamData(connectionId, chunk);
121
+ });
122
+ res.on('end', () => {
123
+ logger.log(`SSE 结束: ${connectionId}`);
124
+ this.notifyStreamEnd(connectionId);
125
+ this.streamingResponses.delete(connectionId);
126
+ });
127
+ res.on('error', (error) => {
128
+ logger.error(`SSE 错误 ${connectionId}:`, error.message);
129
+ this.notifyStreamEnd(connectionId);
130
+ this.streamingResponses.delete(connectionId);
131
+ });
132
+ }
133
+ else {
134
+ // 普通 HTTP 请求,收集完整响应体后一次性发送
135
+ const chunks = [];
136
+ res.on('data', (chunk) => {
137
+ chunks.push(chunk);
138
+ });
139
+ res.on('end', () => {
140
+ const body = Buffer.concat(chunks);
141
+ this.sendResponse(connectionId, {
142
+ statusCode: res.statusCode || 200,
143
+ headers: res.headers,
144
+ body: body.toString('base64'),
145
+ });
146
+ });
147
+ res.on('error', (error) => {
148
+ this.sendError(connectionId, error.message);
149
+ });
150
+ }
151
+ });
152
+ req.on('error', (error) => {
153
+ this.sendError(connectionId, error.message);
154
+ });
155
+ // 发送请求体
156
+ if (body) {
157
+ req.write(Buffer.from(body, 'base64'));
158
+ }
159
+ req.end();
160
+ // 存储请求引用,用于取消
161
+ this.pendingConnections.set(connectionId, { req });
162
+ }
163
+ catch (error) {
164
+ const errorMessage = error instanceof Error ? error.message : String(error);
165
+ this.sendError(connectionId, errorMessage);
166
+ }
167
+ }
168
+ /**
169
+ * 处理来自服务器的新 WebSocket 连接请求。
170
+ */
171
+ handleWebSocketConnection(msg) {
172
+ const { connectionId, url, wsHeaders } = msg.payload;
173
+ logger.log(`WebSocket 连接: ${url} (${connectionId})`);
174
+ // 构建本地 WebSocket URL
175
+ const localUrl = `ws://${this.config.localHost || 'localhost'}:${this.config.localPort}${url}`;
176
+ // 连接到本地 WebSocket 服务
177
+ const localWs = new WebSocket(localUrl, {
178
+ headers: this.filterHeaders(wsHeaders),
179
+ });
180
+ localWs.on('open', () => {
181
+ logger.log(`本地 WebSocket 已连接: ${connectionId}`);
182
+ });
183
+ localWs.on('message', (data) => {
184
+ this.forwardToServer(connectionId, data);
185
+ });
186
+ localWs.on('close', (code, reason) => {
187
+ logger.log(`本地 WebSocket 已关闭: ${connectionId} (${code})`);
188
+ this.notifyServerClose(connectionId, code);
189
+ this.cleanupWsConnection(connectionId);
190
+ });
191
+ localWs.on('error', (error) => {
192
+ logger.error(`本地 WebSocket 错误 ${connectionId}:`, error.message);
193
+ this.notifyServerClose(connectionId, 1011);
194
+ this.cleanupWsConnection(connectionId);
195
+ });
196
+ this.localWsConnections.set(connectionId, localWs);
197
+ }
198
+ /**
199
+ * 将本地数据转发到服务器。
200
+ */
201
+ forwardToServer(connectionId, data) {
202
+ const controller = this.controller;
203
+ if (controller.ws && controller.ws.readyState === WebSocket.OPEN) {
204
+ controller.ws.send(JSON.stringify({
205
+ type: 'connection_data',
206
+ connectionId,
207
+ data: data.toString('base64'),
208
+ }));
209
+ }
210
+ }
211
+ /**
212
+ * 处理从服务器接收到的远程客户端数据。
213
+ */
214
+ handleClientData(connectionId, data) {
215
+ const localWs = this.localWsConnections.get(connectionId);
216
+ if (localWs && localWs.readyState === WebSocket.OPEN) {
217
+ localWs.send(Buffer.from(data, 'base64'));
218
+ }
219
+ }
220
+ /**
221
+ * 将 HTTP 响应数据发送回服务器。
222
+ */
223
+ sendResponse(connectionId, response) {
224
+ const controller = this.controller;
225
+ if (controller.ws && controller.ws.readyState === WebSocket.OPEN) {
226
+ controller.ws.send(JSON.stringify({
227
+ type: 'http_response',
228
+ connectionId,
229
+ ...response,
230
+ }));
231
+ }
232
+ this.pendingConnections.delete(connectionId);
233
+ }
234
+ /**
235
+ * 发送流式响应头(用于 SSE)。
236
+ */
237
+ sendResponseHeaders(connectionId, headers) {
238
+ const controller = this.controller;
239
+ if (controller.ws && controller.ws.readyState === WebSocket.OPEN) {
240
+ controller.ws.send(JSON.stringify({
241
+ type: 'http_response_headers',
242
+ connectionId,
243
+ ...headers,
244
+ }));
245
+ }
246
+ }
247
+ /**
248
+ * 发送流式响应数据块(用于 SSE)。
249
+ */
250
+ forwardStreamData(connectionId, data) {
251
+ const controller = this.controller;
252
+ if (controller.ws && controller.ws.readyState === WebSocket.OPEN) {
253
+ controller.ws.send(JSON.stringify({
254
+ type: 'http_response_data',
255
+ connectionId,
256
+ data: data.toString('base64'),
257
+ }));
258
+ }
259
+ }
260
+ /**
261
+ * 通知服务器流式响应结束(用于 SSE)。
262
+ */
263
+ notifyStreamEnd(connectionId) {
264
+ const controller = this.controller;
265
+ if (controller.ws && controller.ws.readyState === WebSocket.OPEN) {
266
+ controller.ws.send(JSON.stringify({
267
+ type: 'http_response_end',
268
+ connectionId,
269
+ }));
270
+ }
271
+ }
272
+ /**
273
+ * 向服务器发送错误响应。
274
+ */
275
+ sendError(connectionId, error) {
276
+ this.sendResponse(connectionId, {
277
+ statusCode: 500,
278
+ headers: {},
279
+ body: error,
280
+ });
281
+ this.emit('error', new Error(`连接 ${connectionId} 错误: ${error}`));
282
+ }
283
+ /**
284
+ * 通知服务器某个 WebSocket 连接已关闭。
285
+ */
286
+ notifyServerClose(connectionId, code) {
287
+ const closeMsg = createMessage(MessageType.CONNECTION_CLOSE, {
288
+ connectionId,
289
+ });
290
+ this.controller.sendMessage(closeMsg);
291
+ }
292
+ /**
293
+ * 处理来自服务器的连接关闭通知。
294
+ */
295
+ handleConnectionClose(msg) {
296
+ const { connectionId } = msg.payload;
297
+ // 关闭 HTTP 连接
298
+ const pending = this.pendingConnections.get(connectionId);
299
+ if (pending) {
300
+ pending.req.destroy();
301
+ this.pendingConnections.delete(connectionId);
302
+ }
303
+ // 关闭流式响应(如 SSE)
304
+ const streaming = this.streamingResponses.get(connectionId);
305
+ if (streaming) {
306
+ streaming.destroy();
307
+ this.streamingResponses.delete(connectionId);
308
+ }
309
+ // 关闭 WebSocket 连接
310
+ const localWs = this.localWsConnections.get(connectionId);
311
+ if (localWs) {
312
+ localWs.close(1000, '服务器已关闭连接');
313
+ }
314
+ this.cleanupWsConnection(connectionId);
315
+ }
316
+ /**
317
+ * 清理 WebSocket 连接资源。
318
+ */
319
+ cleanupWsConnection(connectionId) {
320
+ const localWs = this.localWsConnections.get(connectionId);
321
+ if (localWs) {
322
+ localWs.removeAllListeners();
323
+ }
324
+ this.localWsConnections.delete(connectionId);
325
+ }
326
+ /**
327
+ * 过滤请求头,移除逐跳头部字段。
328
+ */
329
+ filterHeaders(headers) {
330
+ if (!headers) {
331
+ return {};
332
+ }
333
+ const filtered = {};
334
+ const hopByHopHeaders = [
335
+ 'connection',
336
+ 'keep-alive',
337
+ 'proxy-authenticate',
338
+ 'proxy-authorization',
339
+ 'te',
340
+ 'trailers',
341
+ 'transfer-encoding',
342
+ 'upgrade',
343
+ ];
344
+ for (const [key, value] of Object.entries(headers)) {
345
+ if (!hopByHopHeaders.includes(key.toLowerCase()) && value !== undefined) {
346
+ filtered[key] = Array.isArray(value) ? value.join(', ') : value;
347
+ }
348
+ }
349
+ return filtered;
350
+ }
351
+ /**
352
+ * 销毁处理器,释放所有资源。
353
+ */
354
+ destroy() {
355
+ // 销毁 HTTP 连接
356
+ for (const { req } of this.pendingConnections.values()) {
357
+ req.destroy();
358
+ }
359
+ this.pendingConnections.clear();
360
+ // 销毁流式响应
361
+ for (const res of this.streamingResponses.values()) {
362
+ res.destroy();
363
+ }
364
+ this.streamingResponses.clear();
365
+ // 销毁 WebSocket 连接
366
+ for (const ws of this.localWsConnections.values()) {
367
+ ws.close(1000, '处理器已销毁');
368
+ }
369
+ this.localWsConnections.clear();
370
+ this.removeAllListeners();
371
+ }
372
+ }
373
+ //# sourceMappingURL=unified-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unified-handler.js","sourceRoot":"","sources":["../../src/handlers/unified-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @module @feng3d/ctc
3
+ *
4
+ * 穿透(Chuantou)内网穿透客户端主入口模块。
5
+ *
6
+ * 该模块提供了客户端的核心功能导出和独立运行入口。
7
+ * 作为库使用时,可以导入 {@link Config}、{@link Controller}、{@link ProxyManager} 等核心类;
8
+ * 作为独立程序运行时,会自动加载配置、连接服务器并注册代理隧道。
9
+ */
10
+ /**
11
+ * 导出核心类和类型,供作为库使用时引用。
12
+ */
13
+ export { Config } from './config.js';
14
+ export { Controller } from './controller.js';
15
+ export { ProxyManager } from './proxy-manager.js';
16
+ export { AdminServer } from './admin-server.js';
17
+ export { UnifiedHandler } from './handlers/unified-handler.js';
18
+ export type { ClientConfig, ProxyConfig } from '@feng3d/chuantou-shared';
19
+ /**
20
+ * 导出运行函数供 CLI 使用。
21
+ *
22
+ * 该函数是 {@link main} 的公开包装,用于被 CLI 模块调用以启动客户端。
23
+ *
24
+ * @returns 无返回值的 Promise
25
+ */
26
+ export declare function run(): Promise<void>;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;GAEG;AACH,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,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AA8IzE;;;;;;GAMG;AACH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzC"}
package/dist/index.js ADDED
@@ -0,0 +1,154 @@
1
+ /**
2
+ * @module @feng3d/ctc
3
+ *
4
+ * 穿透(Chuantou)内网穿透客户端主入口模块。
5
+ *
6
+ * 该模块提供了客户端的核心功能导出和独立运行入口。
7
+ * 作为库使用时,可以导入 {@link Config}、{@link Controller}、{@link ProxyManager} 等核心类;
8
+ * 作为独立程序运行时,会自动加载配置、连接服务器并注册代理隧道。
9
+ */
10
+ import { Config } from './config.js';
11
+ import { Controller } from './controller.js';
12
+ import { ProxyManager } from './proxy-manager.js';
13
+ import { AdminServer } from './admin-server.js';
14
+ import { logger } from '@feng3d/chuantou-shared';
15
+ /**
16
+ * 导出核心类和类型,供作为库使用时引用。
17
+ */
18
+ export { Config } from './config.js';
19
+ export { Controller } from './controller.js';
20
+ export { ProxyManager } from './proxy-manager.js';
21
+ export { AdminServer } from './admin-server.js';
22
+ export { UnifiedHandler } from './handlers/unified-handler.js';
23
+ /**
24
+ * 客户端主入口函数(独立运行模式)。
25
+ *
26
+ * 执行以下步骤:
27
+ * 1. 从配置文件或命令行参数加载配置
28
+ * 2. 验证配置合法性
29
+ * 3. 创建控制器并连接服务器
30
+ * 4. 认证成功后注册所有代理隧道
31
+ * 5. 启动本地 HTTP 管理页面服务器
32
+ * 6. 监听进程信号实现优雅关闭
33
+ *
34
+ * @returns 无返回值的 Promise
35
+ */
36
+ async function main() {
37
+ logger.log('正在启动穿透客户端...');
38
+ // 加载配置(从用户目录 .chuantou/client.json 或命令行参数)
39
+ const config = await Config.load();
40
+ // 验证配置
41
+ config.validate();
42
+ logger.log('配置已加载:');
43
+ logger.log(` 服务器地址: ${config.serverUrl}`);
44
+ logger.log(` 代理数量: 已配置 ${config.proxies.length} 个`);
45
+ for (const proxy of config.proxies) {
46
+ logger.log(` - :${proxy.remotePort} -> ${proxy.localHost || 'localhost'}:${proxy.localPort}`);
47
+ }
48
+ // 记录启动时间
49
+ const startTime = Date.now();
50
+ // 创建控制器
51
+ const controller = new Controller(config);
52
+ // 创建代理管理器
53
+ const proxyManager = new ProxyManager(controller);
54
+ // 已注册的代理配置列表(用于管理页面)
55
+ const registeredProxies = [];
56
+ for (const p of config.proxies) {
57
+ registeredProxies.push({ ...p });
58
+ }
59
+ // 创建管理页面服务器
60
+ const adminServer = new AdminServer({ port: 9001, host: '127.0.0.1' },
61
+ // 获取状态回调
62
+ () => ({
63
+ running: true,
64
+ serverUrl: config.serverUrl,
65
+ connected: controller.isConnected(),
66
+ authenticated: controller.isAuthenticated(),
67
+ uptime: Date.now() - startTime,
68
+ proxies: registeredProxies.map(p => ({ ...p })),
69
+ reconnectAttempts: controller.getReconnectAttempts(),
70
+ }),
71
+ // 添加代理回调
72
+ async (proxy) => {
73
+ await proxyManager.registerProxy(proxy);
74
+ registeredProxies.push({ ...proxy });
75
+ },
76
+ // 删除代理回调
77
+ async (remotePort) => {
78
+ await proxyManager.unregisterProxy(remotePort);
79
+ const index = registeredProxies.findIndex(p => p.remotePort === remotePort);
80
+ if (index !== -1) {
81
+ registeredProxies.splice(index, 1);
82
+ }
83
+ });
84
+ // 监听控制器事件
85
+ controller.on('connected', () => {
86
+ logger.log('已连接到服务器');
87
+ });
88
+ controller.on('disconnected', () => {
89
+ logger.log('已断开与服务器的连接');
90
+ });
91
+ controller.on('authenticated', async () => {
92
+ logger.log('已认证,正在注册代理...');
93
+ // 注册所有代理
94
+ for (const proxyConfig of config.proxies) {
95
+ try {
96
+ await proxyManager.registerProxy(proxyConfig);
97
+ // 代理配置已在初始化时添加到 registeredProxies
98
+ }
99
+ catch (error) {
100
+ const errorMessage = error instanceof Error ? error.message : String(error);
101
+ logger.error(`注册代理失败: ${errorMessage}`);
102
+ }
103
+ }
104
+ // 启动管理页面服务器
105
+ try {
106
+ await adminServer.start();
107
+ }
108
+ catch (error) {
109
+ logger.error('管理页面启动失败:', error);
110
+ }
111
+ });
112
+ controller.on('maxReconnectAttemptsReached', () => {
113
+ logger.error('已达到最大重连次数,正在退出...');
114
+ process.exit(1);
115
+ });
116
+ // 优雅关闭
117
+ const shutdown = async () => {
118
+ logger.log('\n正在关闭...');
119
+ await adminServer.stop();
120
+ await proxyManager.destroy();
121
+ controller.disconnect();
122
+ process.exit(0);
123
+ };
124
+ process.on('SIGINT', shutdown);
125
+ process.on('SIGTERM', shutdown);
126
+ // 连接到服务器
127
+ try {
128
+ await controller.connect();
129
+ }
130
+ catch (error) {
131
+ const errorMessage = error instanceof Error ? error.message : String(error);
132
+ logger.error('连接服务器失败:', errorMessage);
133
+ process.exit(1);
134
+ }
135
+ }
136
+ // 检查是否作为主模块运行
137
+ const isMainModule = import.meta.url === `file://${process.argv[1].replace(/\\/g, '/')}`;
138
+ if (isMainModule) {
139
+ main().catch((error) => {
140
+ logger.error('启动客户端失败:', error);
141
+ process.exit(1);
142
+ });
143
+ }
144
+ /**
145
+ * 导出运行函数供 CLI 使用。
146
+ *
147
+ * 该函数是 {@link main} 的公开包装,用于被 CLI 模块调用以启动客户端。
148
+ *
149
+ * @returns 无返回值的 Promise
150
+ */
151
+ export async function run() {
152
+ return main();
153
+ }
154
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @module proxy-manager
3
+ *
4
+ * 代理管理器模块。
5
+ *
6
+ * 负责管理所有代理隧道的生命周期,包括向服务器注册/注销代理、
7
+ * 创建统一的处理器(同时支持 HTTP 和 WebSocket)、
8
+ * 以及在连接断开时清理所有处理器。
9
+ */
10
+ import { Controller } from './controller.js';
11
+ import { ProxyConfig } from '@feng3d/chuantou-shared';
12
+ /**
13
+ * 代理管理器类,负责管理所有代理隧道的注册、注销和生命周期。
14
+ *
15
+ * 创建统一的处理器实例,每个端口同时支持 HTTP 和 WebSocket 协议。
16
+ * 当控制器连接断开时,自动清理所有处理器。
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const proxyManager = new ProxyManager(controller);
21
+ * await proxyManager.registerProxy({ remotePort: 8080, localPort: 3000 });
22
+ * ```
23
+ */
24
+ export declare class ProxyManager {
25
+ /** 控制器实例,用于与服务器通信 */
26
+ private controller;
27
+ /** 代理处理器映射表,键为远程端口号,值为对应的处理器实例 */
28
+ private handlers;
29
+ /**
30
+ * 创建代理管理器实例。
31
+ *
32
+ * @param controller - 控制器实例,用于与服务器进行通信
33
+ */
34
+ constructor(controller: Controller);
35
+ /**
36
+ * 向服务器注册一个代理隧道。
37
+ *
38
+ * 发送注册消息到服务器,注册成功后创建统一的处理器
39
+ * ({@link UnifiedHandler})并存储到处理器映射表中。
40
+ * 每个端口同时支持 HTTP 和 WebSocket 协议。
41
+ *
42
+ * @param config - 代理配置对象,包含远程端口、本地端口等信息
43
+ * @throws {Error} 注册失败时抛出错误,包含服务器返回的错误信息
44
+ */
45
+ registerProxy(config: ProxyConfig): Promise<void>;
46
+ /**
47
+ * 注销指定远程端口的代理隧道。
48
+ *
49
+ * 销毁对应的处理器,并向服务器发送注销请求。
50
+ *
51
+ * @param remotePort - 要注销的代理对应的远程端口号
52
+ */
53
+ unregisterProxy(remotePort: number): Promise<void>;
54
+ /**
55
+ * 注销所有已注册的代理隧道。
56
+ *
57
+ * 并行注销所有代理,等待全部注销完成后返回。
58
+ *
59
+ * @returns 所有代理注销完成后解析的 Promise
60
+ */
61
+ unregisterAll(): Promise<void>;
62
+ /**
63
+ * 处理控制器连接断开事件。
64
+ *
65
+ * 销毁所有处理器并清空处理器映射表。
66
+ */
67
+ private onDisconnected;
68
+ /**
69
+ * 销毁代理管理器,注销所有代理并释放资源。
70
+ *
71
+ * @returns 销毁完成后解析的 Promise
72
+ */
73
+ destroy(): Promise<void>;
74
+ }
75
+ //# sourceMappingURL=proxy-manager.d.ts.map
@@ -0,0 +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;AAI9D;;;;;;;;;;;GAWG;AACH,qBAAa,YAAY;IACvB,qBAAqB;IACrB,OAAO,CAAC,UAAU,CAAa;IAE/B,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAA8B;IAE9C;;;;OAIG;gBACS,UAAU,EAAE,UAAU;IAUlC;;;;;;;;;OASG;IACG,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BvD;;;;;;OAMG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAexD;;;;;;OAMG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAG/B"}