js-tcp-tunnel 1.1.1 → 1.2.1

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/src/lib.test.js CHANGED
@@ -1,652 +1,652 @@
1
- import { test } from 'node:test'
2
- import { ok, strictEqual } from 'node:assert'
3
- import { createTunnelTcpClientHttp, createTunnelTcpClientSocket, createTunnelTcpClientWebSocket, createTunnelTcpServerKoaRouter, createTunnelTcpServerSocket, createTunnelTcpServerWebSocket, formatSize, runWithAbortController, sleep, Uint8Array_toString } from './lib.js'
4
- import net from 'net'
5
- import http from 'http'
6
- import { Readable, Transform } from 'node:stream'
7
- import Koa from 'koa'
8
- import Router from '@koa/router'
9
- import { WebSocketServer } from 'ws'
10
- import log4js from 'log4js'
11
-
12
- log4js.configure({
13
- appenders: { stdout: { type: "stdout", layout: { type: 'pattern', pattern: '[%d{yyyy-MM-dd hh:mm:ss,SSS}] %[%p %m%] %f{2}:%l:%o' } } },
14
- categories: { default: { appenders: ["stdout"], level: "debug", enableCallStack: true } },
15
- })
16
-
17
- /** @type{*} */
18
- const _log4js_ = log4js.getLogger()
19
- _log4js_['table'] = globalThis.console.table
20
- globalThis.console = _log4js_
21
- /** @type{Omit<Console,'log'>} */
22
- const console = _log4js_
23
-
24
- test('tunnel-tcp-socket-test', async () => {
25
- // node --test-name-pattern="^tunnel-tcp-socket-test$" src/lib.test.js
26
-
27
- await runWithAbortController(async ac => {
28
-
29
- console.info('创建socket服务')
30
- let socketServer = net.createServer((socket) => {
31
- socket.pipe(new Transform({
32
- transform(chunk, _, callback) {
33
- // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
34
- this.push(chunk)
35
- callback()
36
- }
37
- })).pipe(socket)
38
- socket.on('error', (err) => {
39
- console.error(err.message)
40
- })
41
- }).listen(9006)
42
- socketServer.on('error', (e) => { console.error(e.message) })
43
- await sleep(100)
44
-
45
- console.info('创建监听服务')
46
- let connection1 = createTunnelTcpClientSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', serverHost: '127.0.0.1', serverPort: 9005, })
47
- connection1.listen({ host: '127.0.0.1', port: 9006, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
48
- await sleep(100)
49
-
50
- console.info('创建连接服务')
51
- let connection2 = createTunnelTcpClientSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', serverHost: '127.0.0.1', serverPort: 9005, })
52
- connection2.connect({ port: 9007, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
53
- await sleep(100)
54
-
55
- console.info('创建转发服务')
56
- createTunnelTcpServerSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', port: 9005, })
57
- await sleep(1000)
58
-
59
- console.info('tcp透传测试')
60
- let socket = net.createConnection({ host: '127.0.0.1', port: 9007 })
61
- socket.on('error', (err) => {
62
- console.error(err.message)
63
- })
64
-
65
- let rec = ''
66
-
67
- await new Promise((resolve) => {
68
- socket.on('connect', async () => {
69
- socket.on('data', (chunk) => {
70
- // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
71
- rec = Uint8Array_toString(chunk)
72
- })
73
- for (let i = 0; i < 100; i++) {
74
- // console.info('send','qwertyuiop - ' + i)
75
- socket.write('qwertyuiop - ' + i)
76
- // await sleep(10)
77
- await sleep(1)
78
- }
79
- await sleep(2000)
80
- resolve()
81
- })
82
- })
83
-
84
- ac.signal.addEventListener('abort', () => {
85
- socket.destroy()
86
- socketServer.close()
87
- })
88
-
89
- let from = rec.length - 'qwertyuiop - 99'.length
90
- strictEqual(rec.substring(from), 'qwertyuiop - 99')
91
-
92
- })
93
- console.info('over!')
94
- })
95
-
96
- test('tunnel-tcp-socket-test-websocket', async () => {
97
- // node --test-name-pattern="^tunnel-tcp-socket-test-websocket$" src/lib.test.js
98
-
99
- await runWithAbortController(async ac => {
100
-
101
- console.info('创建socket服务')
102
- let socketServer = net.createServer((socket) => {
103
- socket.pipe(new Transform({
104
- transform(chunk, _, callback) {
105
- // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
106
- this.push(chunk)
107
- callback()
108
- }
109
- })).pipe(socket)
110
- socket.on('error', (err) => {
111
- console.error(err.message)
112
- })
113
- }).listen(9016)
114
- socketServer.on('error', (e) => { console.error(e.message) })
115
- await sleep(100)
116
-
117
- console.info('创建监听服务')
118
- let connection1 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
119
- connection1.listen({ host: '127.0.0.1', port: 9016, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
120
- await sleep(100)
121
-
122
- console.info('创建连接服务')
123
- let connection2 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
124
- connection2.connect({ port: 9017, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
125
- await sleep(100)
126
-
127
- console.info('创建转发服务')
128
- let server = http.createServer().listen(9015)
129
- server.on('error', (e) => { console.error(e.message) })
130
- let wss = new WebSocketServer({ server })
131
- ac.signal.addEventListener('abort', () => server.close())
132
- createTunnelTcpServerWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', wss, path: '/tunnel/ae145dce31bfa94f0c837749320030bb' })
133
- await sleep(1000)
134
-
135
- console.info('tcp透传测试')
136
- let socket = net.createConnection({ host: '127.0.0.1', port: 9017 })
137
- socket.on('error', (err) => {
138
- console.error(err.message)
139
- })
140
-
141
- let rec = null
142
-
143
- await new Promise((resolve) => {
144
- socket.on('connect', async () => {
145
- socket.on('data', (chunk) => {
146
- // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
147
- rec = Uint8Array_toString(chunk)
148
- })
149
- for (let i = 0; i < 100; i++) {
150
- socket.write('qwertyuiop - ' + i)
151
- await sleep(10)
152
- }
153
- await sleep(100)
154
- resolve()
155
- })
156
- })
157
-
158
- ac.signal.addEventListener('abort', () => {
159
- socket.destroy()
160
- socketServer.close()
161
- })
162
-
163
- strictEqual(rec, 'qwertyuiop - 99')
164
-
165
- })
166
- console.info('over!')
167
- })
168
-
169
- test('tunnel-tcp-socket-test-http', async () => {
170
- // node --test-name-pattern="^tunnel-tcp-socket-test-http$" src/lib.test.js
171
-
172
- await runWithAbortController(async ac => {
173
-
174
- console.info('创建socket服务')
175
- let socketServer = net.createServer((socket) => {
176
- socket.pipe(new Transform({
177
- transform(chunk, _, callback) {
178
- // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
179
- this.push(chunk)
180
- callback()
181
- }
182
- })).pipe(socket)
183
- socket.on('error', (err) => {
184
- console.error(err.message)
185
- })
186
- }).listen(9036)
187
- socketServer.on('error', (e) => { console.error(e.message) })
188
- await sleep(100)
189
-
190
- console.info('创建监听服务')
191
- let connection1 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
192
- connection1.listen({ host: '127.0.0.1', port: 9036, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
193
- await sleep(100)
194
-
195
- console.info('创建连接服务')
196
- let connection2 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
197
- connection2.connect({ port: 9037, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
198
- await sleep(100)
199
-
200
- console.info('创建转发服务')
201
- let app = new Koa()
202
- let router = new Router()
203
- createTunnelTcpServerKoaRouter({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', router: router, path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
204
- app.use(router.routes())
205
- app.use(router.allowedMethods())
206
- app.onerror = (err) => console.info(err.message)
207
- let koaServer = http.createServer(app.callback())
208
- koaServer.listen(9035)
209
- koaServer.on('error', (e) => { console.error(e.message) })
210
- ac.signal.addEventListener('abort', () => { koaServer.close() })
211
- await sleep(1000)
212
-
213
- console.info('tcp透传测试')
214
- let socket = net.createConnection({ host: '127.0.0.1', port: 9037 })
215
- socket.on('error', (err) => {
216
- console.error(err.message)
217
- })
218
-
219
- let rec = null
220
-
221
- await new Promise((resolve) => {
222
- socket.on('connect', async () => {
223
- socket.on('data', (chunk) => {
224
- // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
225
- rec = Uint8Array_toString(chunk)
226
- })
227
- for (let i = 0; i < 100; i++) {
228
- socket.write('qwertyuiop - ' + i)
229
- await sleep(10)
230
- }
231
- await sleep(100)
232
- resolve()
233
- })
234
- })
235
-
236
- ac.signal.addEventListener('abort', () => {
237
- socket.destroy()
238
- socketServer.close()
239
- })
240
-
241
- strictEqual(rec, 'qwertyuiop - 99')
242
-
243
- })
244
- console.info('over!')
245
- })
246
-
247
- test('backpressure-socket', async () => {
248
- // node --test-name-pattern="^backpressure-socket$" src/lib.test.js
249
-
250
- await runWithAbortController(async ac => {
251
-
252
- console.info('创建socket服务')
253
- let transformSize = 0
254
- let socketServer = net.createServer((socket) => {
255
- socket.pipe(new Transform({
256
- transform(chunk, _, callback) {
257
- // console.info('transform chunk', chunk.length)
258
- transformSize += chunk.length
259
- this.push(chunk)
260
- callback()
261
- }
262
- })).pipe(socket).on('error', (err) => console.error(err.message))
263
- }).listen(9036)
264
- await sleep(100)
265
- socketServer.on('error', (err) => {
266
- console.error(err.message)
267
- })
268
-
269
- console.info('创建转发服务 http')
270
- let app = new Koa()
271
- let router = new Router()
272
- createTunnelTcpServerKoaRouter({
273
- signal: ac.signal,
274
- router: router,
275
- path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
276
- serverKey: '2934c57f790f9e99a52a121802df231c',
277
- })
278
- app.use(router.routes())
279
- app.use(router.allowedMethods())
280
- app.onerror = (err) => console.info(err.message)
281
- let koaServer = http.createServer(app.callback())
282
- koaServer.listen(9035)
283
- koaServer.on('error', (e) => { console.error(e.message) })
284
- ac.signal.addEventListener('abort', () => { koaServer.close() })
285
- await sleep(1000)
286
-
287
- console.info('创建监听服务 http')
288
- let connection1 = createTunnelTcpClientHttp({
289
- url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
290
- signal: ac.signal,
291
- serverKey: '2934c57f790f9e99a52a121802df231c',
292
- })
293
- connection1.listen({
294
- clientKey: 'mmm',
295
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
296
- host: '127.0.0.1',
297
- port: 9036,
298
- })
299
- await sleep(100)
300
-
301
- console.info('创建连接服务 http 1')
302
- let connection2 = createTunnelTcpClientHttp({
303
- url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
304
- signal: ac.signal,
305
- serverKey: '2934c57f790f9e99a52a121802df231c',
306
- })
307
- connection2.connect({
308
- clientKey: 'mmm',
309
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
310
- port: 9037,
311
- })
312
-
313
- await sleep(1000)
314
-
315
- console.info('tcp透传测试 start')
316
- let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
317
- socket1.on('error', (err) => { console.error(err.message) })
318
-
319
- let sendWriteSize = 0
320
- let sendSize = 0
321
- let receiveSize = 0
322
- let stop = false
323
- await new Promise((resolve) => {
324
- setTimeout(() => {
325
- stop = true
326
- resolve()
327
- }, 5_000)
328
- socket1.on('connect', async () => {
329
- socket1.pipe(new Transform({
330
- async transform(chunk, _, callback) {
331
- receiveSize += chunk.length
332
- await sleep(500)
333
- callback()
334
- }
335
- })).on('data', (chunk) => {
336
- // console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
337
- })
338
- // let data = new Uint8Array(1024 * 1024)
339
- let data = new Uint8Array(1024)
340
- // let data = Uint8Array_from('1234567890')
341
- let readable = new Readable({
342
- read() {
343
- if (stop) {
344
- this.push(null)
345
- readable.destroy()
346
- return
347
- }
348
- // data = Uint8Array_from('1234567890')
349
- sendSize += data.length
350
- this.push(data)
351
- // stop = true
352
- }
353
- })
354
- readable.on('data', (chunk) => {
355
- sendWriteSize += chunk.length
356
- if (!socket1.write(chunk)) {
357
- readable.pause()
358
- }
359
- })
360
- socket1.on('drain', () => {
361
- readable.resume()
362
- })
363
- // readable.pipe(socket1)
364
- })
365
- })
366
-
367
- console.info(`${'\n'.repeat(3)}sendSize:${formatSize(sendSize)} sendWriteSize:${formatSize(sendWriteSize)} receiveSize:${formatSize(receiveSize)} transformSize:${formatSize(transformSize)}`)
368
-
369
- console.info('tcp透传测试 finish sendSize:', sendSize)
370
-
371
- ac.signal.addEventListener('abort', () => {
372
- socketServer.close()
373
- socket1.destroy()
374
- })
375
-
376
- ok(receiveSize > 640_000)
377
- ok(sendSize < 45000000)
378
-
379
- })
380
- console.info('over!')
381
- })
382
-
383
- // 跳过手动测试
384
- const SKIP_MANAUAL_TEST = true
385
-
386
- test('test-server', { skip: SKIP_MANAUAL_TEST }, async () => {
387
- // node --test-name-pattern="^test-server$" src/lib.test.js
388
- await runWithAbortController(async ac => {
389
- console.info('创建转发服务 http')
390
- let app = new Koa()
391
- let router = new Router()
392
- createTunnelTcpServerKoaRouter({
393
- signal: ac.signal,
394
- router: router,
395
- path: '/tunnel/4b34c9275e1089c79327cba18497a37f',
396
- serverKey: '2934c57f790f9e99a52a121802df231c',
397
- })
398
- app.use(router.routes())
399
- app.use(router.allowedMethods())
400
- app.onerror = (err) => console.info(err.message)
401
- let koaServer = http.createServer(app.callback())
402
- koaServer.listen(9035)
403
- ac.signal.addEventListener('abort', () => { koaServer.close() })
404
- await sleep(10000_000)
405
- })
406
- })
407
- test('test-listen', { skip: SKIP_MANAUAL_TEST }, async () => {
408
- // node --test-name-pattern="^test-listen$" src/lib.test.js
409
- await runWithAbortController(async ac => {
410
- console.info('创建socket服务')
411
- let transformSize = 0
412
- let socketServer = net.createServer((socket) => {
413
- socket.pipe(new Transform({
414
- transform(chunk, _, callback) {
415
- // console.info('transform chunk', chunk.length)
416
- transformSize += chunk.length
417
- this.push(chunk)
418
- callback()
419
- }
420
- })).pipe(socket)
421
- }).listen(9036)
422
- ac.signal.addEventListener('abort', () => { socketServer.close() })
423
- await sleep(100)
424
-
425
- console.info('创建监听服务 http')
426
- let connection = createTunnelTcpClientHttp({
427
- url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
428
- signal: ac.signal,
429
- serverKey: '2934c57f790f9e99a52a121802df231c',
430
- })
431
- connection.listen({
432
- clientKey: 'mmm',
433
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
434
- host: '127.0.0.1',
435
- port: 9036,
436
-
437
- })
438
- await sleep(10000_000)
439
- })
440
- })
441
- test('test-connect', { skip: SKIP_MANAUAL_TEST }, async () => {
442
- // node --test-name-pattern="^test-connect$" src/lib.test.js
443
- await runWithAbortController(async ac => {
444
- console.info('创建连接服务 http 1')
445
- let connection = createTunnelTcpClientHttp({
446
- url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
447
- signal: ac.signal,
448
- serverKey: '2934c57f790f9e99a52a121802df231c',
449
- })
450
- connection.connect({
451
- clientKey: 'mmm',
452
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
453
- port: 9037,
454
- })
455
- await sleep(1000)
456
- console.info('tcp透传测试 start')
457
- let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
458
-
459
- let rec1 = null
460
-
461
- let sendWriteSize = 0
462
- let sendSize = 0
463
- let receiveSize = 0
464
- let stop = false
465
- await new Promise((resolve) => {
466
- // setTimeout(() => {
467
- // stop = true
468
- // resolve()
469
- // }, 5_000)
470
- socket1.on('connect', async () => {
471
- socket1.pipe(new Transform({
472
- async transform(chunk, _, callback) {
473
- receiveSize += chunk.length
474
- await sleep(500)
475
- callback()
476
- }
477
- })).on('data', (chunk) => {
478
- console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
479
- rec1 = Uint8Array_toString(chunk)
480
- })
481
- // let data = new Uint8Array(1024 * 1024)
482
- let data = new Uint8Array(1024)
483
- // let data = Uint8Array_from('1234567890')
484
- let readable = new Readable({
485
- read() {
486
- if (stop) {
487
- this.push(null)
488
- readable.destroy()
489
- return
490
- }
491
- // data = Uint8Array_from('1234567890')
492
- sendSize += data.length
493
- this.push(data)
494
- // stop = true
495
- }
496
- })
497
- readable.on('data', (chunk) => {
498
- sendWriteSize += chunk.length
499
- if (!socket1.write(chunk)) {
500
- readable.pause()
501
- }
502
- })
503
- socket1.on('drain', () => {
504
- readable.resume()
505
- })
506
- readable.pipe(socket1)
507
- })
508
- })
509
-
510
- await sleep(10000_000)
511
- })
512
- })
513
-
514
- test('terminal-server', async () => {
515
- // node --test-name-pattern="^terminal-server$" src/lib.test.js
516
- using stack = new DisposableStack()
517
- const ac = new AbortController()
518
- stack.adopt(ac, () => { ac.abort() })
519
- let transformSize = 0
520
-
521
- async function createEchoServer() {
522
- console.info('创建socket服务')
523
- let socketServer = net.createServer((socket) => {
524
- socket.pipe(new Transform({
525
- transform(chunk, _, callback) {
526
- // console.info('transform chunk', chunk.length)
527
- transformSize += chunk.length
528
- this.push("echo::::")
529
- this.push(chunk)
530
- callback()
531
- }
532
- })).pipe(socket).on('error', (err) => console.error(err.message))
533
- }).listen(9036)
534
- await sleep(100)
535
- socketServer.on('error', (err) => {
536
- console.error(err.message)
537
- })
538
- ac.signal.addEventListener('abort', () => {
539
- socketServer.close()
540
- })
541
- }
542
-
543
- /**
544
- *
545
- * @param {AbortController} ac
546
- */
547
- async function createDispatchServer(ac) {
548
- console.info('创建转发服务 http')
549
- let app = new Koa()
550
- let router = new Router()
551
- createTunnelTcpServerKoaRouter({
552
- signal: ac.signal,
553
- router: router,
554
- path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
555
- serverKey: '2934c57f790f9e99a52a121802df231c',
556
- })
557
- app.use(router.routes())
558
- app.use(router.allowedMethods())
559
- app.onerror = (err) => console.info(err.message)
560
- let koaServer = http.createServer(app.callback())
561
- koaServer.listen(9035)
562
- koaServer.on('error', (e) => { console.error(e.message) })
563
- ac.signal.addEventListener('abort', () => {
564
- console.info('close koa server')
565
- koaServer.close((err) => {
566
- console.info('on server close result ', err)
567
- })
568
- koaServer.closeAllConnections()
569
- })
570
- await sleep(1000)
571
- }
572
-
573
- async function createListenClient() {
574
- console.info('创建监听服务 http')
575
- let connection1 = createTunnelTcpClientHttp({
576
- url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
577
- signal: ac.signal,
578
- serverKey: '2934c57f790f9e99a52a121802df231c',
579
- })
580
- connection1.listen({
581
- clientKey: 'mmm',
582
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
583
- host: '127.0.0.1',
584
- port: 9036,
585
- })
586
- await sleep(100)
587
- }
588
-
589
- async function createConnectClient() {
590
- console.info('创建连接服务 http 1')
591
- let connection2 = createTunnelTcpClientHttp({
592
- url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
593
- signal: ac.signal,
594
- serverKey: '2934c57f790f9e99a52a121802df231c',
595
- })
596
- connection2.connect({
597
- clientKey: 'mmm',
598
- tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
599
- port: 9037,
600
- })
601
-
602
- await sleep(1000)
603
- }
604
-
605
- let socketCreateCount = 0
606
- let recvCount = 0
607
- async function startSendRecvTest() {
608
- socketCreateCount++
609
- console.info('tcp透传测试 start')
610
- let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
611
- socket1.on('error', (err) => { console.error(err.message) })
612
- ac.signal.addEventListener('abort', () => { socket1.destroy() })
613
- socket1.on('connect', async () => {
614
- socket1.on('data', (chunk) => {
615
- console.info('receive chunk ', Uint8Array_toString(chunk))
616
- recvCount++
617
- })
618
- while (!ac.signal.aborted && !socket1.closed) {
619
- await sleep(1000)
620
- socket1.write(`iiiiiii>>>>>>> ${new Date().toLocaleString()}`)
621
- }
622
- console.info('finished socket.')
623
- setTimeout(() => {
624
- startSendRecvTest()
625
- }, 1)
626
- })
627
- }
628
-
629
- await createEchoServer()
630
- let ac2 = new AbortController()
631
- stack.adopt(0, () => ac2.abort())
632
- await createDispatchServer(ac2)
633
- await createListenClient()
634
- await createConnectClient()
635
- await startSendRecvTest()
636
-
637
- await sleep(5000)
638
- ac2.abort()
639
- console.info('stop dispatch server')
640
- await sleep(5_000)
641
- ac2 = new AbortController()
642
- stack.adopt(0, () => ac2.abort())
643
- console.info('recreate dispatch server')
644
- await createDispatchServer(ac2)
645
-
646
- await sleep(20_000)
647
-
648
- strictEqual(socketCreateCount, 2)
649
- strictEqual(recvCount, 14)
650
-
651
- console.info('over!')
1
+ import { test } from 'node:test'
2
+ import { ok, strictEqual } from 'node:assert'
3
+ import { createTunnelTcpClientHttp, createTunnelTcpClientSocket, createTunnelTcpClientWebSocket, createTunnelTcpServerKoaRouter, createTunnelTcpServerSocket, createTunnelTcpServerWebSocket, formatSize, runWithAbortController, sleep, Uint8Array_toString } from './lib.js'
4
+ import net from 'net'
5
+ import http from 'http'
6
+ import { Readable, Transform } from 'node:stream'
7
+ import Koa from 'koa'
8
+ import Router from '@koa/router'
9
+ import { WebSocketServer } from 'ws'
10
+ import log4js from 'log4js'
11
+
12
+ log4js.configure({
13
+ appenders: { stdout: { type: "stdout", layout: { type: 'pattern', pattern: '[%d{yyyy-MM-dd hh:mm:ss,SSS}] %[%p %m%] %f{2}:%l:%o' } } },
14
+ categories: { default: { appenders: ["stdout"], level: "debug", enableCallStack: true } },
15
+ })
16
+
17
+ /** @type{*} */
18
+ const _log4js_ = log4js.getLogger()
19
+ _log4js_['table'] = globalThis.console.table
20
+ globalThis.console = _log4js_
21
+ /** @type{Omit<Console,'log'>} */
22
+ const console = _log4js_
23
+
24
+ test('tunnel-tcp-socket-test', async () => {
25
+ // node --test-name-pattern="^tunnel-tcp-socket-test$" src/lib.test.js
26
+
27
+ await runWithAbortController(async ac => {
28
+
29
+ console.info('创建socket服务')
30
+ let socketServer = net.createServer((socket) => {
31
+ socket.pipe(new Transform({
32
+ transform(chunk, _, callback) {
33
+ // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
34
+ this.push(chunk)
35
+ callback()
36
+ }
37
+ })).pipe(socket)
38
+ socket.on('error', (err) => {
39
+ console.error(err.message)
40
+ })
41
+ }).listen(9006)
42
+ socketServer.on('error', (e) => { console.error(e.message) })
43
+ await sleep(100)
44
+
45
+ console.info('创建监听服务')
46
+ let connection1 = createTunnelTcpClientSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', serverHost: '127.0.0.1', serverPort: 9005, })
47
+ connection1.listen({ host: '127.0.0.1', port: 9006, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
48
+ await sleep(100)
49
+
50
+ console.info('创建连接服务')
51
+ let connection2 = createTunnelTcpClientSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', serverHost: '127.0.0.1', serverPort: 9005, })
52
+ connection2.connect({ port: 9007, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
53
+ await sleep(100)
54
+
55
+ console.info('创建转发服务')
56
+ createTunnelTcpServerSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', port: 9005, })
57
+ await sleep(1000)
58
+
59
+ console.info('tcp透传测试')
60
+ let socket = net.createConnection({ host: '127.0.0.1', port: 9007 })
61
+ socket.on('error', (err) => {
62
+ console.error(err.message)
63
+ })
64
+
65
+ let rec = ''
66
+
67
+ await new Promise((resolve) => {
68
+ socket.on('connect', async () => {
69
+ socket.on('data', (chunk) => {
70
+ // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
71
+ rec = Uint8Array_toString(chunk)
72
+ })
73
+ for (let i = 0; i < 100; i++) {
74
+ // console.info('send','qwertyuiop - ' + i)
75
+ socket.write('qwertyuiop - ' + i)
76
+ // await sleep(10)
77
+ await sleep(1)
78
+ }
79
+ await sleep(2000)
80
+ resolve()
81
+ })
82
+ })
83
+
84
+ ac.signal.addEventListener('abort', () => {
85
+ socket.destroy()
86
+ socketServer.close()
87
+ })
88
+
89
+ let from = rec.length - 'qwertyuiop - 99'.length
90
+ strictEqual(rec.substring(from), 'qwertyuiop - 99')
91
+
92
+ })
93
+ console.info('over!')
94
+ })
95
+
96
+ test('tunnel-tcp-socket-test-websocket', async () => {
97
+ // node --test-name-pattern="^tunnel-tcp-socket-test-websocket$" src/lib.test.js
98
+
99
+ await runWithAbortController(async ac => {
100
+
101
+ console.info('创建socket服务')
102
+ let socketServer = net.createServer((socket) => {
103
+ socket.pipe(new Transform({
104
+ transform(chunk, _, callback) {
105
+ // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
106
+ this.push(chunk)
107
+ callback()
108
+ }
109
+ })).pipe(socket)
110
+ socket.on('error', (err) => {
111
+ console.error(err.message)
112
+ })
113
+ }).listen(9016)
114
+ socketServer.on('error', (e) => { console.error(e.message) })
115
+ await sleep(100)
116
+
117
+ console.info('创建监听服务')
118
+ let connection1 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
119
+ connection1.listen({ host: '127.0.0.1', port: 9016, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
120
+ await sleep(100)
121
+
122
+ console.info('创建连接服务')
123
+ let connection2 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
124
+ connection2.connect({ port: 9017, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
125
+ await sleep(100)
126
+
127
+ console.info('创建转发服务')
128
+ let server = http.createServer().listen(9015)
129
+ server.on('error', (e) => { console.error(e.message) })
130
+ let wss = new WebSocketServer({ server })
131
+ ac.signal.addEventListener('abort', () => server.close())
132
+ createTunnelTcpServerWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', wss, path: '/tunnel/ae145dce31bfa94f0c837749320030bb' })
133
+ await sleep(1000)
134
+
135
+ console.info('tcp透传测试')
136
+ let socket = net.createConnection({ host: '127.0.0.1', port: 9017 })
137
+ socket.on('error', (err) => {
138
+ console.error(err.message)
139
+ })
140
+
141
+ let rec = null
142
+
143
+ await new Promise((resolve) => {
144
+ socket.on('connect', async () => {
145
+ socket.on('data', (chunk) => {
146
+ // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
147
+ rec = Uint8Array_toString(chunk)
148
+ })
149
+ for (let i = 0; i < 100; i++) {
150
+ socket.write('qwertyuiop - ' + i)
151
+ await sleep(10)
152
+ }
153
+ await sleep(100)
154
+ resolve()
155
+ })
156
+ })
157
+
158
+ ac.signal.addEventListener('abort', () => {
159
+ socket.destroy()
160
+ socketServer.close()
161
+ })
162
+
163
+ strictEqual(rec, 'qwertyuiop - 99')
164
+
165
+ })
166
+ console.info('over!')
167
+ })
168
+
169
+ test('tunnel-tcp-socket-test-http', async () => {
170
+ // node --test-name-pattern="^tunnel-tcp-socket-test-http$" src/lib.test.js
171
+
172
+ await runWithAbortController(async ac => {
173
+
174
+ console.info('创建socket服务')
175
+ let socketServer = net.createServer((socket) => {
176
+ socket.pipe(new Transform({
177
+ transform(chunk, _, callback) {
178
+ // console.info('transform chunk', chunk, Uint8Array_toString(chunk))
179
+ this.push(chunk)
180
+ callback()
181
+ }
182
+ })).pipe(socket)
183
+ socket.on('error', (err) => {
184
+ console.error(err.message)
185
+ })
186
+ }).listen(9036)
187
+ socketServer.on('error', (e) => { console.error(e.message) })
188
+ await sleep(100)
189
+
190
+ console.info('创建监听服务')
191
+ let connection1 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
192
+ connection1.listen({ host: '127.0.0.1', port: 9036, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
193
+ await sleep(100)
194
+
195
+ console.info('创建连接服务')
196
+ let connection2 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
197
+ connection2.connect({ port: 9037, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
198
+ await sleep(100)
199
+
200
+ console.info('创建转发服务')
201
+ let app = new Koa()
202
+ let router = new Router()
203
+ createTunnelTcpServerKoaRouter({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', router: router, path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
204
+ app.use(router.routes())
205
+ app.use(router.allowedMethods())
206
+ app.onerror = (err) => console.info(err.message)
207
+ let koaServer = http.createServer(app.callback())
208
+ koaServer.listen(9035)
209
+ koaServer.on('error', (e) => { console.error(e.message) })
210
+ ac.signal.addEventListener('abort', () => { koaServer.close() })
211
+ await sleep(1000)
212
+
213
+ console.info('tcp透传测试')
214
+ let socket = net.createConnection({ host: '127.0.0.1', port: 9037 })
215
+ socket.on('error', (err) => {
216
+ console.error(err.message)
217
+ })
218
+
219
+ let rec = null
220
+
221
+ await new Promise((resolve) => {
222
+ socket.on('connect', async () => {
223
+ socket.on('data', (chunk) => {
224
+ // console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
225
+ rec = Uint8Array_toString(chunk)
226
+ })
227
+ for (let i = 0; i < 100; i++) {
228
+ socket.write('qwertyuiop - ' + i)
229
+ await sleep(10)
230
+ }
231
+ await sleep(100)
232
+ resolve()
233
+ })
234
+ })
235
+
236
+ ac.signal.addEventListener('abort', () => {
237
+ socket.destroy()
238
+ socketServer.close()
239
+ })
240
+
241
+ strictEqual(rec, 'qwertyuiop - 99')
242
+
243
+ })
244
+ console.info('over!')
245
+ })
246
+
247
+ test('backpressure-socket', async () => {
248
+ // node --test-name-pattern="^backpressure-socket$" src/lib.test.js
249
+
250
+ await runWithAbortController(async ac => {
251
+
252
+ console.info('创建socket服务')
253
+ let transformSize = 0
254
+ let socketServer = net.createServer((socket) => {
255
+ socket.pipe(new Transform({
256
+ transform(chunk, _, callback) {
257
+ // console.info('transform chunk', chunk.length)
258
+ transformSize += chunk.length
259
+ this.push(chunk)
260
+ callback()
261
+ }
262
+ })).pipe(socket).on('error', (err) => console.error(err.message))
263
+ }).listen(9036)
264
+ await sleep(100)
265
+ socketServer.on('error', (err) => {
266
+ console.error(err.message)
267
+ })
268
+
269
+ console.info('创建转发服务 http')
270
+ let app = new Koa()
271
+ let router = new Router()
272
+ createTunnelTcpServerKoaRouter({
273
+ signal: ac.signal,
274
+ router: router,
275
+ path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
276
+ serverKey: '2934c57f790f9e99a52a121802df231c',
277
+ })
278
+ app.use(router.routes())
279
+ app.use(router.allowedMethods())
280
+ app.onerror = (err) => console.info(err.message)
281
+ let koaServer = http.createServer(app.callback())
282
+ koaServer.listen(9035)
283
+ koaServer.on('error', (e) => { console.error(e.message) })
284
+ ac.signal.addEventListener('abort', () => { koaServer.close() })
285
+ await sleep(1000)
286
+
287
+ console.info('创建监听服务 http')
288
+ let connection1 = createTunnelTcpClientHttp({
289
+ url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
290
+ signal: ac.signal,
291
+ serverKey: '2934c57f790f9e99a52a121802df231c',
292
+ })
293
+ connection1.listen({
294
+ clientKey: 'mmm',
295
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
296
+ host: '127.0.0.1',
297
+ port: 9036,
298
+ })
299
+ await sleep(100)
300
+
301
+ console.info('创建连接服务 http 1')
302
+ let connection2 = createTunnelTcpClientHttp({
303
+ url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
304
+ signal: ac.signal,
305
+ serverKey: '2934c57f790f9e99a52a121802df231c',
306
+ })
307
+ connection2.connect({
308
+ clientKey: 'mmm',
309
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
310
+ port: 9037,
311
+ })
312
+
313
+ await sleep(1000)
314
+
315
+ console.info('tcp透传测试 start')
316
+ let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
317
+ socket1.on('error', (err) => { console.error(err.message) })
318
+
319
+ let sendWriteSize = 0
320
+ let sendSize = 0
321
+ let receiveSize = 0
322
+ let stop = false
323
+ await new Promise((resolve) => {
324
+ setTimeout(() => {
325
+ stop = true
326
+ resolve()
327
+ }, 5_000)
328
+ socket1.on('connect', async () => {
329
+ socket1.pipe(new Transform({
330
+ async transform(chunk, _, callback) {
331
+ receiveSize += chunk.length
332
+ await sleep(500)
333
+ callback()
334
+ }
335
+ })).on('data', (chunk) => {
336
+ // console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
337
+ })
338
+ // let data = new Uint8Array(1024 * 1024)
339
+ let data = new Uint8Array(1024)
340
+ // let data = Uint8Array_from('1234567890')
341
+ let readable = new Readable({
342
+ read() {
343
+ if (stop) {
344
+ this.push(null)
345
+ readable.destroy()
346
+ return
347
+ }
348
+ // data = Uint8Array_from('1234567890')
349
+ sendSize += data.length
350
+ this.push(data)
351
+ // stop = true
352
+ }
353
+ })
354
+ readable.on('data', (chunk) => {
355
+ sendWriteSize += chunk.length
356
+ if (!socket1.write(chunk)) {
357
+ readable.pause()
358
+ }
359
+ })
360
+ socket1.on('drain', () => {
361
+ readable.resume()
362
+ })
363
+ // readable.pipe(socket1)
364
+ })
365
+ })
366
+
367
+ console.info(`${'\n'.repeat(3)}sendSize:${formatSize(sendSize)} sendWriteSize:${formatSize(sendWriteSize)} receiveSize:${formatSize(receiveSize)} transformSize:${formatSize(transformSize)}`)
368
+
369
+ console.info('tcp透传测试 finish sendSize:', sendSize)
370
+
371
+ ac.signal.addEventListener('abort', () => {
372
+ socketServer.close()
373
+ socket1.destroy()
374
+ })
375
+
376
+ ok(receiveSize > 640_000)
377
+ ok(sendSize < 45000000)
378
+
379
+ })
380
+ console.info('over!')
381
+ })
382
+
383
+ // 跳过手动测试
384
+ const SKIP_MANAUAL_TEST = true
385
+
386
+ test('test-server', { skip: SKIP_MANAUAL_TEST }, async () => {
387
+ // node --test-name-pattern="^test-server$" src/lib.test.js
388
+ await runWithAbortController(async ac => {
389
+ console.info('创建转发服务 http')
390
+ let app = new Koa()
391
+ let router = new Router()
392
+ createTunnelTcpServerKoaRouter({
393
+ signal: ac.signal,
394
+ router: router,
395
+ path: '/tunnel/4b34c9275e1089c79327cba18497a37f',
396
+ serverKey: '2934c57f790f9e99a52a121802df231c',
397
+ })
398
+ app.use(router.routes())
399
+ app.use(router.allowedMethods())
400
+ app.onerror = (err) => console.info(err.message)
401
+ let koaServer = http.createServer(app.callback())
402
+ koaServer.listen(9035)
403
+ ac.signal.addEventListener('abort', () => { koaServer.close() })
404
+ await sleep(10000_000)
405
+ })
406
+ })
407
+ test('test-listen', { skip: SKIP_MANAUAL_TEST }, async () => {
408
+ // node --test-name-pattern="^test-listen$" src/lib.test.js
409
+ await runWithAbortController(async ac => {
410
+ console.info('创建socket服务')
411
+ let transformSize = 0
412
+ let socketServer = net.createServer((socket) => {
413
+ socket.pipe(new Transform({
414
+ transform(chunk, _, callback) {
415
+ // console.info('transform chunk', chunk.length)
416
+ transformSize += chunk.length
417
+ this.push(chunk)
418
+ callback()
419
+ }
420
+ })).pipe(socket)
421
+ }).listen(9036)
422
+ ac.signal.addEventListener('abort', () => { socketServer.close() })
423
+ await sleep(100)
424
+
425
+ console.info('创建监听服务 http')
426
+ let connection = createTunnelTcpClientHttp({
427
+ url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
428
+ signal: ac.signal,
429
+ serverKey: '2934c57f790f9e99a52a121802df231c',
430
+ })
431
+ connection.listen({
432
+ clientKey: 'mmm',
433
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
434
+ host: '127.0.0.1',
435
+ port: 9036,
436
+
437
+ })
438
+ await sleep(10000_000)
439
+ })
440
+ })
441
+ test('test-connect', { skip: SKIP_MANAUAL_TEST }, async () => {
442
+ // node --test-name-pattern="^test-connect$" src/lib.test.js
443
+ await runWithAbortController(async ac => {
444
+ console.info('创建连接服务 http 1')
445
+ let connection = createTunnelTcpClientHttp({
446
+ url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
447
+ signal: ac.signal,
448
+ serverKey: '2934c57f790f9e99a52a121802df231c',
449
+ })
450
+ connection.connect({
451
+ clientKey: 'mmm',
452
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
453
+ port: 9037,
454
+ })
455
+ await sleep(1000)
456
+ console.info('tcp透传测试 start')
457
+ let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
458
+
459
+ let rec1 = null
460
+
461
+ let sendWriteSize = 0
462
+ let sendSize = 0
463
+ let receiveSize = 0
464
+ let stop = false
465
+ await new Promise((resolve) => {
466
+ // setTimeout(() => {
467
+ // stop = true
468
+ // resolve()
469
+ // }, 5_000)
470
+ socket1.on('connect', async () => {
471
+ socket1.pipe(new Transform({
472
+ async transform(chunk, _, callback) {
473
+ receiveSize += chunk.length
474
+ await sleep(500)
475
+ callback()
476
+ }
477
+ })).on('data', (chunk) => {
478
+ console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
479
+ rec1 = Uint8Array_toString(chunk)
480
+ })
481
+ // let data = new Uint8Array(1024 * 1024)
482
+ let data = new Uint8Array(1024)
483
+ // let data = Uint8Array_from('1234567890')
484
+ let readable = new Readable({
485
+ read() {
486
+ if (stop) {
487
+ this.push(null)
488
+ readable.destroy()
489
+ return
490
+ }
491
+ // data = Uint8Array_from('1234567890')
492
+ sendSize += data.length
493
+ this.push(data)
494
+ // stop = true
495
+ }
496
+ })
497
+ readable.on('data', (chunk) => {
498
+ sendWriteSize += chunk.length
499
+ if (!socket1.write(chunk)) {
500
+ readable.pause()
501
+ }
502
+ })
503
+ socket1.on('drain', () => {
504
+ readable.resume()
505
+ })
506
+ readable.pipe(socket1)
507
+ })
508
+ })
509
+
510
+ await sleep(10000_000)
511
+ })
512
+ })
513
+
514
+ test('terminal-server', async () => {
515
+ // node --test-name-pattern="^terminal-server$" src/lib.test.js
516
+ using stack = new DisposableStack()
517
+ const ac = new AbortController()
518
+ stack.adopt(ac, () => { ac.abort() })
519
+ let transformSize = 0
520
+
521
+ async function createEchoServer() {
522
+ console.info('创建socket服务')
523
+ let socketServer = net.createServer((socket) => {
524
+ socket.pipe(new Transform({
525
+ transform(chunk, _, callback) {
526
+ // console.info('transform chunk', chunk.length)
527
+ transformSize += chunk.length
528
+ this.push("echo::::")
529
+ this.push(chunk)
530
+ callback()
531
+ }
532
+ })).pipe(socket).on('error', (err) => console.error(err.message))
533
+ }).listen(9036)
534
+ await sleep(100)
535
+ socketServer.on('error', (err) => {
536
+ console.error(err.message)
537
+ })
538
+ ac.signal.addEventListener('abort', () => {
539
+ socketServer.close()
540
+ })
541
+ }
542
+
543
+ /**
544
+ *
545
+ * @param {AbortController} ac
546
+ */
547
+ async function createDispatchServer(ac) {
548
+ console.info('创建转发服务 http')
549
+ let app = new Koa()
550
+ let router = new Router()
551
+ createTunnelTcpServerKoaRouter({
552
+ signal: ac.signal,
553
+ router: router,
554
+ path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
555
+ serverKey: '2934c57f790f9e99a52a121802df231c',
556
+ })
557
+ app.use(router.routes())
558
+ app.use(router.allowedMethods())
559
+ app.onerror = (err) => console.info(err.message)
560
+ let koaServer = http.createServer(app.callback())
561
+ koaServer.listen(9035)
562
+ koaServer.on('error', (e) => { console.error(e.message) })
563
+ ac.signal.addEventListener('abort', () => {
564
+ console.info('close koa server')
565
+ koaServer.close((err) => {
566
+ console.info('on server close result ', err)
567
+ })
568
+ koaServer.closeAllConnections()
569
+ })
570
+ await sleep(1000)
571
+ }
572
+
573
+ async function createListenClient() {
574
+ console.info('创建监听服务 http')
575
+ let connection1 = createTunnelTcpClientHttp({
576
+ url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
577
+ signal: ac.signal,
578
+ serverKey: '2934c57f790f9e99a52a121802df231c',
579
+ })
580
+ connection1.listen({
581
+ clientKey: 'mmm',
582
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
583
+ host: '127.0.0.1',
584
+ port: 9036,
585
+ })
586
+ await sleep(100)
587
+ }
588
+
589
+ async function createConnectClient() {
590
+ console.info('创建连接服务 http 1')
591
+ let connection2 = createTunnelTcpClientHttp({
592
+ url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
593
+ signal: ac.signal,
594
+ serverKey: '2934c57f790f9e99a52a121802df231c',
595
+ })
596
+ connection2.connect({
597
+ clientKey: 'mmm',
598
+ tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
599
+ port: 9037,
600
+ })
601
+
602
+ await sleep(1000)
603
+ }
604
+
605
+ let socketCreateCount = 0
606
+ let recvCount = 0
607
+ async function startSendRecvTest() {
608
+ socketCreateCount++
609
+ console.info('tcp透传测试 start')
610
+ let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
611
+ socket1.on('error', (err) => { console.error(err.message) })
612
+ ac.signal.addEventListener('abort', () => { socket1.destroy() })
613
+ socket1.on('connect', async () => {
614
+ socket1.on('data', (chunk) => {
615
+ console.info('receive chunk ', Uint8Array_toString(chunk))
616
+ recvCount++
617
+ })
618
+ while (!ac.signal.aborted && !socket1.closed) {
619
+ await sleep(1000)
620
+ socket1.write(`iiiiiii>>>>>>> ${new Date().toLocaleString()}`)
621
+ }
622
+ console.info('finished socket.')
623
+ setTimeout(() => {
624
+ startSendRecvTest()
625
+ }, 1)
626
+ })
627
+ }
628
+
629
+ await createEchoServer()
630
+ let ac2 = new AbortController()
631
+ stack.adopt(0, () => ac2.abort())
632
+ await createDispatchServer(ac2)
633
+ await createListenClient()
634
+ await createConnectClient()
635
+ await startSendRecvTest()
636
+
637
+ await sleep(5000)
638
+ ac2.abort()
639
+ console.info('stop dispatch server')
640
+ await sleep(5_000)
641
+ ac2 = new AbortController()
642
+ stack.adopt(0, () => ac2.abort())
643
+ console.info('recreate dispatch server')
644
+ await createDispatchServer(ac2)
645
+
646
+ await sleep(20_000)
647
+
648
+ strictEqual(socketCreateCount, 1)
649
+ strictEqual(recvCount, 25)
650
+
651
+ console.info('over!')
652
652
  })