@cjwddz/mirror 1.1.0 → 1.2.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.
Files changed (85) hide show
  1. package/README.md +89 -222
  2. package/dist/cli/client.d.ts +19 -0
  3. package/dist/cli/client.d.ts.map +1 -0
  4. package/dist/cli/client.js +107 -0
  5. package/dist/cli/client.js.map +1 -0
  6. package/dist/cli/index.d.ts +1 -1
  7. package/dist/cli/index.js +88 -51
  8. package/dist/cli/index.js.map +1 -1
  9. package/dist/cli/server.d.ts +19 -0
  10. package/dist/cli/server.d.ts.map +1 -0
  11. package/dist/cli/server.js +82 -0
  12. package/dist/cli/server.js.map +1 -0
  13. package/dist/core/http-tunnel-client.d.ts +64 -0
  14. package/dist/core/http-tunnel-client.d.ts.map +1 -0
  15. package/dist/core/http-tunnel-client.js +315 -0
  16. package/dist/core/http-tunnel-client.js.map +1 -0
  17. package/dist/core/http-tunnel-protocol.d.ts +86 -0
  18. package/dist/core/http-tunnel-protocol.d.ts.map +1 -0
  19. package/dist/core/http-tunnel-protocol.js +29 -0
  20. package/dist/core/http-tunnel-protocol.js.map +1 -0
  21. package/dist/core/http-tunnel-server.d.ts +74 -0
  22. package/dist/core/http-tunnel-server.d.ts.map +1 -0
  23. package/dist/core/http-tunnel-server.js +317 -0
  24. package/dist/core/http-tunnel-server.js.map +1 -0
  25. package/dist/index.d.ts +4 -8
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +4 -8
  28. package/dist/index.js.map +1 -1
  29. package/package.json +12 -10
  30. package/dist/cli/exec.d.ts +0 -9
  31. package/dist/cli/exec.d.ts.map +0 -1
  32. package/dist/cli/exec.js +0 -32
  33. package/dist/cli/exec.js.map +0 -1
  34. package/dist/cli/host-impl.d.ts +0 -58
  35. package/dist/cli/host-impl.d.ts.map +0 -1
  36. package/dist/cli/host-impl.js +0 -547
  37. package/dist/cli/host-impl.js.map +0 -1
  38. package/dist/cli/host.d.ts +0 -9
  39. package/dist/cli/host.d.ts.map +0 -1
  40. package/dist/cli/host.js +0 -57
  41. package/dist/cli/host.js.map +0 -1
  42. package/dist/cli/link.d.ts +0 -10
  43. package/dist/cli/link.d.ts.map +0 -1
  44. package/dist/cli/link.js +0 -105
  45. package/dist/cli/link.js.map +0 -1
  46. package/dist/cli/logs.d.ts +0 -8
  47. package/dist/cli/logs.d.ts.map +0 -1
  48. package/dist/cli/logs.js +0 -48
  49. package/dist/cli/logs.js.map +0 -1
  50. package/dist/cli/shell.d.ts +0 -6
  51. package/dist/cli/shell.d.ts.map +0 -1
  52. package/dist/cli/shell.js +0 -53
  53. package/dist/cli/shell.js.map +0 -1
  54. package/dist/cli/status.d.ts +0 -6
  55. package/dist/cli/status.d.ts.map +0 -1
  56. package/dist/cli/status.js +0 -33
  57. package/dist/cli/status.js.map +0 -1
  58. package/dist/cli/stop.d.ts +0 -6
  59. package/dist/cli/stop.d.ts.map +0 -1
  60. package/dist/cli/stop.js +0 -18
  61. package/dist/cli/stop.js.map +0 -1
  62. package/dist/cli/ui/MirrorUI.d.ts +0 -22
  63. package/dist/cli/ui/MirrorUI.d.ts.map +0 -1
  64. package/dist/cli/ui/MirrorUI.js +0 -71
  65. package/dist/cli/ui/MirrorUI.js.map +0 -1
  66. package/dist/cli/ui/interactive-terminal.d.ts +0 -3
  67. package/dist/cli/ui/interactive-terminal.d.ts.map +0 -1
  68. package/dist/cli/ui/interactive-terminal.js +0 -150
  69. package/dist/cli/ui/interactive-terminal.js.map +0 -1
  70. package/dist/cli/watch.d.ts +0 -6
  71. package/dist/cli/watch.d.ts.map +0 -1
  72. package/dist/cli/watch.js +0 -29
  73. package/dist/cli/watch.js.map +0 -1
  74. package/dist/core/daemon.d.ts +0 -154
  75. package/dist/core/daemon.d.ts.map +0 -1
  76. package/dist/core/daemon.js +0 -590
  77. package/dist/core/daemon.js.map +0 -1
  78. package/dist/core/process-manager.d.ts +0 -19
  79. package/dist/core/process-manager.d.ts.map +0 -1
  80. package/dist/core/process-manager.js +0 -76
  81. package/dist/core/process-manager.js.map +0 -1
  82. package/dist/transport/pty.d.ts +0 -7
  83. package/dist/transport/pty.d.ts.map +0 -1
  84. package/dist/transport/pty.js +0 -26
  85. package/dist/transport/pty.js.map +0 -1
package/README.md CHANGED
@@ -1,15 +1,14 @@
1
- # Mirror —— 开发态远程工作空间镜像工具
1
+ # Mirror —— HTTP 隧道工具
2
2
 
3
- 开发态远程工作空间镜像工具,将本地项目目录镜像到远程服务器,并在远程执行命令。
3
+ HTTP 隧道工具,将本地服务暴露到公网,无需公网 IP 或配置路由器。
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - ✅ 全量文件同步(SNAPSHOT)
8
- - ✅ 增量文件同步(FILE_DIFF)
9
- - ✅ 远程命令执行(PTY 支持)
10
- - ✅ 文件变更实时监听
11
- - ✅ 状态机保证一致性
12
- - ✅ 一次性 workspace,完全可丢弃
7
+ - ✅ 将本地 HTTP 服务暴露到公网
8
+ - ✅ WebSocket 隧道,低延迟高性能
9
+ - ✅ 支持自定义端口和认证令牌
10
+ - ✅ 自动重连机制
11
+ - ✅ 支持并发请求
13
12
 
14
13
  ## 安装
15
14
 
@@ -19,128 +18,92 @@ npm install -g @cjwddz/mirror
19
18
 
20
19
  ## 使用方法
21
20
 
22
- ### 1. 启动 Host(远程服务器)
21
+ ### 1. 启动服务端(公网服务器)
23
22
 
24
- ```bash
25
- mirror host --port 7331
26
- ```
27
-
28
- 或者指定 token:
23
+ 在有公网 IP 的服务器上运行:
29
24
 
30
25
  ```bash
31
- mirror host --port 7331 --token my-custom-token
26
+ mirror server --port 80 --tunnel-port 7332
32
27
  ```
33
28
 
34
29
  可选参数:
35
30
 
36
- - `--port <port>`: 端口号(默认: 7331
37
- - `--tmp-dir <dir>`: 临时目录(默认: /tmp
38
- - `--ignore <patterns>`: 忽略的文件模式,逗号分隔(默认: node_modules,.git
39
- - `--token <token>`: 指定 session token(不指定则自动生成)
40
-
41
- 启动后会显示连接地址:
42
-
43
- ```
44
- Mirror host started
45
- Listening on :7331
46
-
47
- Connect using:
48
- mirror link 192.168.1.100:7331?token=KJ82mZpX...
49
- ```
31
+ - `--port <port>`: HTTP 服务端口(默认: 80
32
+ - `--tunnel-port <port>`: WebSocket 隧道端口(默认: 7332
33
+ - `--host <host>`: 监听地址(默认: 0.0.0.0
34
+ - `--token <token>`: 认证令牌(可选,建议设置)
35
+ - `--timeout <ms>`: 请求超时时间(毫秒,默认: 30000)
50
36
 
51
- ### 2. 连接 Client(本地开发机)
37
+ ### 2. 启动客户端(本地开发机)
52
38
 
53
- 在项目目录中执行:
54
-
55
- **使用 IP 和端口连接:**
39
+ 在本地开发机上运行:
56
40
 
57
41
  ```bash
58
- mirror link 192.168.1.100:7331?token=KJ82mZpX...
42
+ mirror client ws://your-server.com:7332 http://localhost:3000
59
43
  ```
60
44
 
61
- **使用域名连接(支持反向代理):**
45
+ 参数说明:
62
46
 
63
- ```bash
64
- # HTTP (ws://)
65
- mirror link ws://mirror.example.com?token=KJ82mZpX...
47
+ - `serverUrl`: 服务端 WebSocket 地址,格式: `ws://host[:port]`
48
+ - `targetUrl`: 本地服务地址,格式: `http://localhost:port`
66
49
 
67
- # HTTPS (wss://)
68
- mirror link wss://mirror.example.com?token=KJ82mZpX...
69
- ```
70
-
71
- **URL 格式说明:**
72
-
73
- - 格式:`[ws://|wss://]host[:port]?token=xxx`
74
- - `ws://` 或 `wss://` 协议前缀可选(默认 `ws://`)
75
- - `port` 可选,如果使用反向代理可以不指定端口
76
- - `token` 必需,用于身份验证
77
-
78
- 连接成功后:
79
-
80
- 1. 自动进行全量文件同步
81
- 2. 启动文件监听(增量同步)
82
- 3. 进入交互式终端
83
-
84
- 在交互式终端中输入命令,命令会在远程服务器的工作空间中执行。
85
-
86
- 输入 `exit` 或 `quit` 退出。
87
-
88
- ## 工作原理
89
-
90
- ### 状态机(v0.1.0 简化版)
50
+ 可选参数:
91
51
 
92
- Host 维护以下状态:
52
+ - `--token <token>`: 认证令牌(与服务端设置的一致)
53
+ - `--reconnect-interval <ms>`: 重连间隔(毫秒,默认: 5000)
54
+ - `--max-retries <number>`: 最大重试次数(默认: 10)
93
55
 
94
- - `EMPTY`: 无 client 连接
95
- - `SYNCING`: 初始全量文件同步中
96
- - `READY`: 就绪状态(可执行命令,可同步文件)
56
+ ### 3. 访问服务
97
57
 
98
- **改进说明:**
58
+ 客户端连接成功后,访问服务端地址即可访问本地服务:
99
59
 
100
- - 移除了 `RUNNING` 状态,使用独立标志位跟踪命令执行
101
- - 文件同步和命令执行完全解耦,互不干扰
102
- - 解决了长时间运行命令时文件同步卡死的问题
60
+ ```bash
61
+ # 例如,本地运行了一个服务在 localhost:3000
62
+ # 服务端地址是 your-server.com
63
+ # 现在可以通过 http://your-server.com 访问本地服务
64
+ ```
103
65
 
104
- ### Workspace Version
66
+ ## 使用示例
105
67
 
106
- - version 为单调递增整数
107
- - 由 client 生成
108
- - exec 时必须声明 version
109
- - host 仅在 `exec.version === currentVersion` 时允许执行
68
+ ### 基本用法
110
69
 
111
- ### 文件同步
70
+ ```bash
71
+ # 服务端(服务器)
72
+ mirror server --port 80 --tunnel-port 7332
112
73
 
113
- - **全量同步(SNAPSHOT)**: 连接时一次性同步所有文件
114
- - **增量同步(FILE_DIFF)**: 文件变更时实时同步
115
- - 无论是否有命令在执行,文件变更都会**立即同步**到远程
116
- - 使用原子写入保证文件一致性
117
- - 不再使用 pending 队列机制
74
+ # 客户端(本地)
75
+ mirror client ws://your-server.com:7332 http://localhost:3000
76
+ ```
118
77
 
119
- **改进说明:**
78
+ ### 使用认证令牌
120
79
 
121
- - ✅ 修复了 `npm run start` 等长时间运行命令时文件同步卡死的问题
122
- - ✅ 文件变更实时生效,开发体验更流畅
123
- - 类似本地开发,文件保存后立即可用
80
+ ```bash
81
+ # 服务端
82
+ mirror server --port 80 --tunnel-port 7332 --token my-secret-token
124
83
 
125
- ### 进程管理
84
+ # 客户端
85
+ mirror client ws://your-server.com:7332 http://localhost:3000 --token my-secret-token
86
+ ```
126
87
 
127
- - 使用 PTY 支持交互式命令
128
- - 命令执行在独立的进程组中
129
- - 断开连接时自动清理所有进程
88
+ ### 自定义端口
130
89
 
131
- ## Nginx 反向代理配置
90
+ ```bash
91
+ # 服务端监听 8080 端口,隧道端口 7332
92
+ mirror server --port 8080 --tunnel-port 7332
132
93
 
133
- 如果需要在生产环境中通过域名访问,可以使用 Nginx 作为反向代理。
94
+ # 客户端连接到 7332 端口
95
+ mirror client ws://your-server.com:7332 http://localhost:3000
96
+ ```
134
97
 
135
- ### 基本配置(HTTP)
98
+ ### 使用 Nginx 反向代理
136
99
 
137
100
  ```nginx
138
101
  server {
139
102
  listen 80;
140
- server_name mirror.example.com;
103
+ server_name tunnel.example.com;
141
104
 
142
105
  location / {
143
- proxy_pass http://127.0.0.1:7331;
106
+ proxy_pass http://127.0.0.1:80;
144
107
  proxy_http_version 1.1;
145
108
 
146
109
  # WebSocket 升级
@@ -158,169 +121,73 @@ server {
158
121
  proxy_send_timeout 7d;
159
122
  proxy_read_timeout 7d;
160
123
  }
161
- }
162
- ```
163
-
164
- ### HTTPS 配置(推荐)
165
-
166
- ```nginx
167
- server {
168
- listen 443 ssl http2;
169
- server_name mirror.example.com;
170
-
171
- # SSL 证书配置
172
- ssl_certificate /path/to/cert.pem;
173
- ssl_certificate_key /path/to/key.pem;
174
-
175
- # SSL 优化
176
- ssl_protocols TLSv1.2 TLSv1.3;
177
- ssl_ciphers HIGH:!aNULL:!MD5;
178
- ssl_prefer_server_ciphers on;
179
124
 
180
- location / {
181
- proxy_pass http://127.0.0.1:7331;
125
+ location /tunnel {
126
+ proxy_pass http://127.0.0.1:7332;
182
127
  proxy_http_version 1.1;
183
128
 
184
- # WebSocket 升级
185
129
  proxy_set_header Upgrade $http_upgrade;
186
130
  proxy_set_header Connection "upgrade";
187
131
 
188
- # 传递原始信息
189
132
  proxy_set_header Host $host;
190
133
  proxy_set_header X-Real-IP $remote_addr;
191
134
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
192
- proxy_set_header X-Forwarded-Proto $scheme;
193
135
 
194
- # 超时设置(WebSocket 连接可能需要长时间保持)
195
136
  proxy_connect_timeout 7d;
196
137
  proxy_send_timeout 7d;
197
138
  proxy_read_timeout 7d;
198
139
  }
199
140
  }
200
-
201
- # HTTP 重定向到 HTTPS
202
- server {
203
- listen 80;
204
- server_name mirror.example.com;
205
- return 301 https://$server_name$request_uri;
206
- }
207
141
  ```
208
142
 
209
- ### 配置说明
210
-
211
- 1. **WebSocket 升级**:`proxy_set_header Upgrade` 和 `Connection "upgrade"` 是必需的,用于将 HTTP 连接升级为 WebSocket
212
- 2. **超时设置**:WebSocket 连接可能需要长时间保持,建议设置较长的超时时间(如 7 天)
213
- 3. **端口映射**:将 `127.0.0.1:7331` 替换为实际的 mirror host 服务地址和端口
214
- 4. **SSL 证书**:使用 HTTPS 时,需要配置有效的 SSL 证书
215
-
216
- 配置完成后,客户端可以使用以下方式连接:
143
+ 客户端连接时使用域名:
217
144
 
218
145
  ```bash
219
- # HTTPS (推荐)
220
- mirror link wss://mirror.example.com?token=KJ82mZpX...
221
-
222
- # HTTP (不推荐,仅用于测试)
223
- mirror link ws://mirror.example.com?token=KJ82mZpX...
146
+ mirror client ws://tunnel.example.com/tunnel http://localhost:3000
224
147
  ```
225
148
 
226
- ## 故障排查
227
-
228
- ### 502 Bad Gateway 错误
229
-
230
- 如果连接时遇到 502 错误,通常表示 Nginx 无法连接到后端 mirror host 服务。请检查:
231
-
232
- 1. **mirror host 服务是否运行**:
233
-
234
- ```bash
235
- # 在服务器上检查
236
- ps aux | grep mirror
237
- netstat -tlnp | grep 7331
238
- ```
239
-
240
- 2. **Nginx 配置中的 proxy_pass 地址是否正确**:
241
-
242
- ```nginx
243
- proxy_pass http://127.0.0.1:7331; # 确保端口和地址正确
244
- ```
245
-
246
- 3. **查看 Nginx 错误日志**:
247
- ```bash
248
- tail -f /var/log/nginx/error.log
249
- ```
250
-
251
- 更多详细的排查步骤请参考 [TROUBLESHOOTING.md](./TROUBLESHOOTING.md)
252
-
253
- ### 协议选择
254
-
255
- - 如果域名配置了 HTTPS,**必须使用 `wss://` 协议**
256
- - 如果域名只配置了 HTTP,使用 `ws://` 协议
257
- - 使用 IP 地址连接时,根据实际情况选择协议
149
+ ## 工作原理
258
150
 
259
- 示例:
151
+ Mirror 通过 WebSocket 建立隧道,将客户端和服务端连接起来:
260
152
 
261
- ```bash
262
- # HTTPS 域名(推荐)
263
- mirror link wss://mirror.example.com?token=xxx
153
+ 1. **服务端**:监听 HTTP 端口,接收外部请求
154
+ 2. **客户端**:连接到服务端 WebSocket 隧道
155
+ 3. **请求转发**:服务端将 HTTP 请求通过隧道转发给客户端
156
+ 4. **响应返回**:客户端将请求转发给本地服务,获取响应后返回给服务端
157
+ 5. **外部访问**:用户访问服务端地址,实际访问的是本地服务
264
158
 
265
- # HTTP 域名(不推荐)
266
- mirror link ws://mirror.example.com?token=xxx
267
159
  ```
268
-
269
- ## 新特性
270
-
271
- ### 🎯 实时文件同步(v0.1.0)
272
-
273
- 文件变更实时同步到远程,无论是否有命令在执行:
274
-
275
- ```bash
276
- > npm run start
277
- Server listening on port 3000
278
- [同步] 同步中: src/index.ts (update) ← 实时同步,不干扰命令输出
279
- [同步] ✓ 已同步: src/index.ts ← 2秒后自动清除
160
+ 用户 → 服务端 (HTTP) → WebSocket 隧道 → 客户端 → 本地服务
280
161
  ```
281
162
 
282
- **优势:**
283
-
284
- - ✅ 不再有 pending 队列,文件立即同步
285
- - ✅ 长时间运行的命令不会阻塞文件同步
286
- - ✅ 开发体验更流畅,类似本地开发
287
-
288
- ### 🎯 改进的 Ctrl+C 退出逻辑
163
+ ## 注意事项
289
164
 
290
- - **第一次 Ctrl+C**:发送中断信号给远程进程(中断命令)
291
- - **第二次 Ctrl+C**(3秒内):退出 mirror 客户端
292
- - **无命令运行时**:第一次直接退出
165
+ - ⚠️ 服务端需要有公网 IP 或可访问的网络地址
166
+ - ⚠️ 使用认证令牌可以提高安全性
167
+ - ⚠️ 建议使用 Nginx 等 Web 服务器做反向代理
168
+ - ⚠️ 确保防火墙开放相应端口
169
+ - ℹ️ 仅用于开发和测试,不建议在生产环境中使用
293
170
 
294
- ```bash
295
- > npm run start
296
- Server listening...
297
- ^C (发送中断信号到远程进程,再次按 Ctrl+C 退出 mirror)
298
- Server shutting down...
299
- > _ # 命令中断,mirror 继续运行
300
-
301
- # 如需退出 mirror,再按一次 Ctrl+C
302
- ```
171
+ ## 故障排查
303
172
 
304
- ### 🎯 命令输出与状态信息分离
173
+ ### 无法连接
305
174
 
306
- - 状态信息使用灰色单行显示,不干扰命令输出
307
- - 状态信息会在 1 秒后自动清除
308
- - 命令输出正常显示,与状态信息互不干扰
175
+ 1. 检查服务端是否正常运行
176
+ 2. 检查防火墙是否开放端口
177
+ 3. 检查 WebSocket 隧道端口是否正确
178
+ 4. 检查认证令牌是否匹配
309
179
 
310
- 详细使用说明请参考:
180
+ ### 请求超时
311
181
 
312
- - [使用改进说明.md](./使用改进说明.md) - 中文详细说明
313
- - [IMPROVEMENTS.md](./IMPROVEMENTS.md) - English technical details
182
+ 1. 检查本地服务是否正常运行
183
+ 2. 增加 `--timeout` 参数值
184
+ 3. 检查网络连接是否稳定
314
185
 
315
- ## 注意事项
186
+ ### 频繁断线
316
187
 
317
- - ⚠️ 仅用于开发阶段,不适用于生产环境
318
- - ⚠️ 不支持多 client 并发(新连接会抢占旧连接)
319
- - ⚠️ workspace 是临时的,断开连接后自动清理
320
- - ⚠️ 不支持恢复,需要重新连接
321
- - ⚠️ 使用域名连接时,确保使用正确的协议(HTTPS 使用 wss://,HTTP 使用 ws://)
322
- - ⚠️ 使用反向代理时,确保 Nginx 配置了正确的 WebSocket 升级头
323
- - ℹ️ 新特性需要客户端和服务端版本匹配才能使用
188
+ 1. 检查网络稳定性
189
+ 2. 调整 `--reconnect-interval` 参数
190
+ 3. 检查服务端资源使用情况
324
191
 
325
192
  ## 开发
326
193
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Mirror HTTP Tunnel Client CLI 命令
3
+ * 连接到服务端,将 HTTP 请求转发到本地服务
4
+ */
5
+ /**
6
+ * 客户端配置选项
7
+ */
8
+ export interface ClientOptions {
9
+ serverUrl: string;
10
+ targetUrl: string;
11
+ token?: string;
12
+ reconnectInterval: number;
13
+ maxRetries: number;
14
+ }
15
+ /**
16
+ * 启动 HTTP 隧道客户端
17
+ */
18
+ export declare function clientCommand(options: ClientOptions): Promise<void>;
19
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqHzE"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Mirror HTTP Tunnel Client CLI 命令
3
+ * 连接到服务端,将 HTTP 请求转发到本地服务
4
+ */
5
+ import { WebSocket } from 'ws';
6
+ import { HttpTunnelClient } from '../core/http-tunnel-client.js';
7
+ /**
8
+ * 启动 HTTP 隧道客户端
9
+ */
10
+ export async function clientCommand(options) {
11
+ const { serverUrl, targetUrl, token, reconnectInterval, maxRetries } = options;
12
+ console.log('Mirror HTTP Tunnel Client');
13
+ console.log('=========================\n');
14
+ console.log(`[*] Server URL: ${serverUrl}`);
15
+ console.log(`[*] Target URL: ${targetUrl}`);
16
+ if (token) {
17
+ console.log(`[*] Authentication token: ${token}`);
18
+ }
19
+ console.log();
20
+ let tunnelWs = null;
21
+ let tunnelClient = null;
22
+ let retryCount = 0;
23
+ /**
24
+ * 连接到服务器
25
+ */
26
+ const connect = () => {
27
+ // 构建 WebSocket URL(添加 token)
28
+ let wsUrl = serverUrl;
29
+ if (token) {
30
+ const urlObj = new URL(wsUrl);
31
+ if (!urlObj.searchParams.has('token')) {
32
+ const separator = wsUrl.includes('?') ? '&' : '?';
33
+ wsUrl = `${wsUrl}${separator}token=${token}`;
34
+ }
35
+ }
36
+ console.log(`[*] Connecting to server (attempt ${retryCount + 1}/${maxRetries})...`);
37
+ tunnelWs = new WebSocket(wsUrl);
38
+ tunnelWs.on('open', () => {
39
+ console.log('[✓] WebSocket connected\n');
40
+ retryCount = 0; // 重置重试计数器
41
+ // 等待欢迎消息后再创建 HTTP 隧道客户端
42
+ });
43
+ tunnelWs.on('message', (data) => {
44
+ try {
45
+ const message = JSON.parse(data.toString());
46
+ // 处理欢迎消息
47
+ if (message.type === 'WELCOME') {
48
+ console.log(`[✓] ${message.message}`);
49
+ console.log(`[*] Server version: ${message.serverVersion}`);
50
+ console.log('[*] HTTP tunnel is now active\n');
51
+ // 收到欢迎消息后,创建 HTTP 隧道客户端
52
+ if (!tunnelClient && tunnelWs) {
53
+ tunnelClient = new HttpTunnelClient({
54
+ targetUrl,
55
+ tunnelWs,
56
+ });
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ // 忽略解析错误
62
+ }
63
+ });
64
+ tunnelWs.on('close', (code, reason) => {
65
+ const reasonStr = reason ? reason.toString() : 'Unknown reason';
66
+ console.log(`[!] Disconnected from server: ${reasonStr} (code: ${code})\n`);
67
+ if (tunnelClient) {
68
+ tunnelClient.close();
69
+ tunnelClient = null;
70
+ }
71
+ // 尝试重新连接
72
+ if (retryCount < maxRetries) {
73
+ retryCount++;
74
+ console.log(`[*] Reconnecting in ${reconnectInterval / 1000} seconds...`);
75
+ setTimeout(connect, reconnectInterval);
76
+ }
77
+ else {
78
+ console.log('[!] Max retry attempts reached. Giving up.');
79
+ process.exit(1);
80
+ }
81
+ });
82
+ tunnelWs.on('error', (error) => {
83
+ console.error('[!] Connection error:', error.message);
84
+ // 不要退出,让 close 事件处理重连
85
+ });
86
+ };
87
+ // 初始连接
88
+ connect();
89
+ // 处理进程退出
90
+ const cleanup = () => {
91
+ console.log('\n[*] Shutting down...');
92
+ if (tunnelClient) {
93
+ tunnelClient.close();
94
+ tunnelClient = null;
95
+ }
96
+ if (tunnelWs) {
97
+ tunnelWs.close();
98
+ tunnelWs = null;
99
+ }
100
+ process.exit(0);
101
+ };
102
+ process.on('SIGINT', cleanup);
103
+ process.on('SIGTERM', cleanup);
104
+ // 防止进程退出
105
+ await new Promise(() => { });
106
+ }
107
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/cli/client.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Mirror CLI 入口
3
+ * Mirror CLI 入口 - HTTP 隧道工具
4
4
  */
5
5
  export {};
6
6
  //# sourceMappingURL=index.d.ts.map