js-tcp-tunnel 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/jsconfig.json +29 -0
- package/package.json +33 -0
- package/src/lib.js +1539 -0
- package/src/lib.test.js +511 -0
package/src/lib.test.js
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
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 = null
|
|
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
|
+
strictEqual(rec, 'qwertyuiop - 99')
|
|
90
|
+
|
|
91
|
+
})
|
|
92
|
+
console.info('over!')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('tunnel-tcp-socket-test-websocket', async () => {
|
|
96
|
+
// node --test-name-pattern="^tunnel-tcp-socket-test-websocket$" src/lib.test.js
|
|
97
|
+
|
|
98
|
+
await runWithAbortController(async ac => {
|
|
99
|
+
|
|
100
|
+
console.info('创建socket服务')
|
|
101
|
+
let socketServer = net.createServer((socket) => {
|
|
102
|
+
socket.pipe(new Transform({
|
|
103
|
+
transform(chunk, _, callback) {
|
|
104
|
+
// console.info('transform chunk', chunk, Uint8Array_toString(chunk))
|
|
105
|
+
this.push(chunk)
|
|
106
|
+
callback()
|
|
107
|
+
}
|
|
108
|
+
})).pipe(socket)
|
|
109
|
+
socket.on('error', (err) => {
|
|
110
|
+
console.error(err.message)
|
|
111
|
+
})
|
|
112
|
+
}).listen(9016)
|
|
113
|
+
socketServer.on('error', (e) => { console.error(e.message) })
|
|
114
|
+
await sleep(100)
|
|
115
|
+
|
|
116
|
+
console.info('创建监听服务')
|
|
117
|
+
let connection1 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
|
|
118
|
+
connection1.listen({ host: '127.0.0.1', port: 9016, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
|
|
119
|
+
await sleep(100)
|
|
120
|
+
|
|
121
|
+
console.info('创建连接服务')
|
|
122
|
+
let connection2 = createTunnelTcpClientWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'ws://127.0.0.1:9015/tunnel/ae145dce31bfa94f0c837749320030bb', })
|
|
123
|
+
connection2.connect({ port: 9017, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
|
|
124
|
+
await sleep(100)
|
|
125
|
+
|
|
126
|
+
console.info('创建转发服务')
|
|
127
|
+
let server = http.createServer().listen(9015)
|
|
128
|
+
server.on('error', (e) => { console.error(e.message) })
|
|
129
|
+
let wss = new WebSocketServer({ server })
|
|
130
|
+
ac.signal.addEventListener('abort', () => server.close())
|
|
131
|
+
createTunnelTcpServerWebSocket({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', wss, path: '/tunnel/ae145dce31bfa94f0c837749320030bb' })
|
|
132
|
+
await sleep(1000)
|
|
133
|
+
|
|
134
|
+
console.info('tcp透传测试')
|
|
135
|
+
let socket = net.createConnection({ host: '127.0.0.1', port: 9017 })
|
|
136
|
+
socket.on('error', (err) => {
|
|
137
|
+
console.error(err.message)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
let rec = null
|
|
141
|
+
|
|
142
|
+
await new Promise((resolve) => {
|
|
143
|
+
socket.on('connect', async () => {
|
|
144
|
+
socket.on('data', (chunk) => {
|
|
145
|
+
// console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
|
|
146
|
+
rec = Uint8Array_toString(chunk)
|
|
147
|
+
})
|
|
148
|
+
for (let i = 0; i < 100; i++) {
|
|
149
|
+
socket.write('qwertyuiop - ' + i)
|
|
150
|
+
await sleep(10)
|
|
151
|
+
}
|
|
152
|
+
await sleep(100)
|
|
153
|
+
resolve()
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
ac.signal.addEventListener('abort', () => {
|
|
158
|
+
socket.destroy()
|
|
159
|
+
socketServer.close()
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
strictEqual(rec, 'qwertyuiop - 99')
|
|
163
|
+
|
|
164
|
+
})
|
|
165
|
+
console.info('over!')
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test('tunnel-tcp-socket-test-http', async () => {
|
|
169
|
+
// node --test-name-pattern="^tunnel-tcp-socket-test-http$" src/lib.test.js
|
|
170
|
+
|
|
171
|
+
await runWithAbortController(async ac => {
|
|
172
|
+
|
|
173
|
+
console.info('创建socket服务')
|
|
174
|
+
let socketServer = net.createServer((socket) => {
|
|
175
|
+
socket.pipe(new Transform({
|
|
176
|
+
transform(chunk, _, callback) {
|
|
177
|
+
// console.info('transform chunk', chunk, Uint8Array_toString(chunk))
|
|
178
|
+
this.push(chunk)
|
|
179
|
+
callback()
|
|
180
|
+
}
|
|
181
|
+
})).pipe(socket)
|
|
182
|
+
socket.on('error', (err) => {
|
|
183
|
+
console.error(err.message)
|
|
184
|
+
})
|
|
185
|
+
}).listen(9036)
|
|
186
|
+
socketServer.on('error', (e) => { console.error(e.message) })
|
|
187
|
+
await sleep(100)
|
|
188
|
+
|
|
189
|
+
console.info('创建监听服务')
|
|
190
|
+
let connection1 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
|
|
191
|
+
connection1.listen({ host: '127.0.0.1', port: 9036, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
|
|
192
|
+
await sleep(100)
|
|
193
|
+
|
|
194
|
+
console.info('创建连接服务')
|
|
195
|
+
let connection2 = createTunnelTcpClientHttp({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
|
|
196
|
+
connection2.connect({ port: 9037, tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f', })
|
|
197
|
+
await sleep(100)
|
|
198
|
+
|
|
199
|
+
console.info('创建转发服务')
|
|
200
|
+
let app = new Koa()
|
|
201
|
+
let router = new Router()
|
|
202
|
+
createTunnelTcpServerKoaRouter({ signal: ac.signal, serverKey: '2934c57f790f9e99a52a121802df231c', router: router, path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04', })
|
|
203
|
+
app.use(router.routes())
|
|
204
|
+
app.use(router.allowedMethods())
|
|
205
|
+
app.onerror = (err) => console.info(err.message)
|
|
206
|
+
let koaServer = http.createServer(app.callback())
|
|
207
|
+
koaServer.listen(9035)
|
|
208
|
+
koaServer.on('error', (e) => { console.error(e.message) })
|
|
209
|
+
ac.signal.addEventListener('abort', () => { koaServer.close() })
|
|
210
|
+
await sleep(1000)
|
|
211
|
+
|
|
212
|
+
console.info('tcp透传测试')
|
|
213
|
+
let socket = net.createConnection({ host: '127.0.0.1', port: 9037 })
|
|
214
|
+
socket.on('error', (err) => {
|
|
215
|
+
console.error(err.message)
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
let rec = null
|
|
219
|
+
|
|
220
|
+
await new Promise((resolve) => {
|
|
221
|
+
socket.on('connect', async () => {
|
|
222
|
+
socket.on('data', (chunk) => {
|
|
223
|
+
// console.info('receive chunk ', chunk, Uint8Array_toString(chunk))
|
|
224
|
+
rec = Uint8Array_toString(chunk)
|
|
225
|
+
})
|
|
226
|
+
for (let i = 0; i < 100; i++) {
|
|
227
|
+
socket.write('qwertyuiop - ' + i)
|
|
228
|
+
await sleep(10)
|
|
229
|
+
}
|
|
230
|
+
await sleep(100)
|
|
231
|
+
resolve()
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
ac.signal.addEventListener('abort', () => {
|
|
236
|
+
socket.destroy()
|
|
237
|
+
socketServer.close()
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
strictEqual(rec, 'qwertyuiop - 99')
|
|
241
|
+
|
|
242
|
+
})
|
|
243
|
+
console.info('over!')
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
test('backpressure-socket', async () => {
|
|
247
|
+
// node --test-name-pattern="^backpressure-socket$" src/lib.test.js
|
|
248
|
+
|
|
249
|
+
await runWithAbortController(async ac => {
|
|
250
|
+
|
|
251
|
+
console.info('创建socket服务')
|
|
252
|
+
let transformSize = 0
|
|
253
|
+
let socketServer = net.createServer((socket) => {
|
|
254
|
+
socket.pipe(new Transform({
|
|
255
|
+
transform(chunk, _, callback) {
|
|
256
|
+
// console.info('transform chunk', chunk.length)
|
|
257
|
+
transformSize += chunk.length
|
|
258
|
+
this.push(chunk)
|
|
259
|
+
callback()
|
|
260
|
+
}
|
|
261
|
+
})).pipe(socket).on('error', (err) => console.error(err.message))
|
|
262
|
+
}).listen(9036)
|
|
263
|
+
await sleep(100)
|
|
264
|
+
socketServer.on('error', (err) => {
|
|
265
|
+
console.error(err.message)
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
console.info('创建转发服务 http')
|
|
269
|
+
let app = new Koa()
|
|
270
|
+
let router = new Router()
|
|
271
|
+
createTunnelTcpServerKoaRouter({
|
|
272
|
+
signal: ac.signal,
|
|
273
|
+
router: router,
|
|
274
|
+
path: '/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
|
|
275
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
276
|
+
})
|
|
277
|
+
app.use(router.routes())
|
|
278
|
+
app.use(router.allowedMethods())
|
|
279
|
+
app.onerror = (err) => console.info(err.message)
|
|
280
|
+
let koaServer = http.createServer(app.callback())
|
|
281
|
+
koaServer.listen(9035)
|
|
282
|
+
koaServer.on('error', (e) => { console.error(e.message) })
|
|
283
|
+
ac.signal.addEventListener('abort', () => { koaServer.close() })
|
|
284
|
+
await sleep(1000)
|
|
285
|
+
|
|
286
|
+
console.info('创建监听服务 http')
|
|
287
|
+
let connection1 = createTunnelTcpClientHttp({
|
|
288
|
+
url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
|
|
289
|
+
signal: ac.signal,
|
|
290
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
291
|
+
})
|
|
292
|
+
connection1.listen({
|
|
293
|
+
clientKey: 'mmm',
|
|
294
|
+
tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
|
|
295
|
+
host: '127.0.0.1',
|
|
296
|
+
port: 9036,
|
|
297
|
+
})
|
|
298
|
+
await sleep(100)
|
|
299
|
+
|
|
300
|
+
console.info('创建连接服务 http 1')
|
|
301
|
+
let connection2 = createTunnelTcpClientHttp({
|
|
302
|
+
url: 'http://127.0.0.1:9035/tunnel/0f7c5b2c9080eaa9e4d6139126daac04',
|
|
303
|
+
signal: ac.signal,
|
|
304
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
305
|
+
})
|
|
306
|
+
connection2.connect({
|
|
307
|
+
clientKey: 'mmm',
|
|
308
|
+
tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
|
|
309
|
+
port: 9037,
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
await sleep(1000)
|
|
313
|
+
|
|
314
|
+
console.info('tcp透传测试 start')
|
|
315
|
+
let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
|
|
316
|
+
socket1.on('error', (err) => { console.error(err.message) })
|
|
317
|
+
|
|
318
|
+
let sendWriteSize = 0
|
|
319
|
+
let sendSize = 0
|
|
320
|
+
let receiveSize = 0
|
|
321
|
+
let stop = false
|
|
322
|
+
await new Promise((resolve) => {
|
|
323
|
+
setTimeout(() => {
|
|
324
|
+
stop = true
|
|
325
|
+
resolve()
|
|
326
|
+
}, 5_000)
|
|
327
|
+
socket1.on('connect', async () => {
|
|
328
|
+
socket1.pipe(new Transform({
|
|
329
|
+
async transform(chunk, _, callback) {
|
|
330
|
+
receiveSize += chunk.length
|
|
331
|
+
await sleep(500)
|
|
332
|
+
callback()
|
|
333
|
+
}
|
|
334
|
+
})).on('data', (chunk) => {
|
|
335
|
+
// console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
|
|
336
|
+
})
|
|
337
|
+
// let data = new Uint8Array(1024 * 1024)
|
|
338
|
+
let data = new Uint8Array(1024)
|
|
339
|
+
// let data = Uint8Array_from('1234567890')
|
|
340
|
+
let readable = new Readable({
|
|
341
|
+
read() {
|
|
342
|
+
if (stop) {
|
|
343
|
+
this.push(null)
|
|
344
|
+
readable.destroy()
|
|
345
|
+
return
|
|
346
|
+
}
|
|
347
|
+
// data = Uint8Array_from('1234567890')
|
|
348
|
+
sendSize += data.length
|
|
349
|
+
this.push(data)
|
|
350
|
+
// stop = true
|
|
351
|
+
}
|
|
352
|
+
})
|
|
353
|
+
readable.on('data', (chunk) => {
|
|
354
|
+
sendWriteSize += chunk.length
|
|
355
|
+
if (!socket1.write(chunk)) {
|
|
356
|
+
readable.pause()
|
|
357
|
+
}
|
|
358
|
+
})
|
|
359
|
+
socket1.on('drain', () => {
|
|
360
|
+
readable.resume()
|
|
361
|
+
})
|
|
362
|
+
// readable.pipe(socket1)
|
|
363
|
+
})
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
console.info(`${'\n'.repeat(3)}sendSize:${formatSize(sendSize)} sendWriteSize:${formatSize(sendWriteSize)} receiveSize:${formatSize(receiveSize)} transformSize:${formatSize(transformSize)}`)
|
|
367
|
+
|
|
368
|
+
console.info('tcp透传测试 finish sendSize:', sendSize)
|
|
369
|
+
|
|
370
|
+
ac.signal.addEventListener('abort', () => {
|
|
371
|
+
socketServer.close()
|
|
372
|
+
socket1.destroy()
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
ok(receiveSize > 640_000)
|
|
376
|
+
ok(sendSize < 45000000)
|
|
377
|
+
|
|
378
|
+
})
|
|
379
|
+
console.info('over!')
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
// 跳过手动测试
|
|
383
|
+
const SKIP_MANAUAL_TEST = true
|
|
384
|
+
|
|
385
|
+
test('test-server', { skip: SKIP_MANAUAL_TEST }, async () => {
|
|
386
|
+
// node --test-name-pattern="^test-server$" src/lib.test.js
|
|
387
|
+
await runWithAbortController(async ac => {
|
|
388
|
+
console.info('创建转发服务 http')
|
|
389
|
+
let app = new Koa()
|
|
390
|
+
let router = new Router()
|
|
391
|
+
createTunnelTcpServerKoaRouter({
|
|
392
|
+
signal: ac.signal,
|
|
393
|
+
router: router,
|
|
394
|
+
path: '/tunnel/4b34c9275e1089c79327cba18497a37f',
|
|
395
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
396
|
+
})
|
|
397
|
+
app.use(router.routes())
|
|
398
|
+
app.use(router.allowedMethods())
|
|
399
|
+
app.onerror = (err) => console.info(err.message)
|
|
400
|
+
let koaServer = http.createServer(app.callback())
|
|
401
|
+
koaServer.listen(9035)
|
|
402
|
+
ac.signal.addEventListener('abort', () => { koaServer.close() })
|
|
403
|
+
await sleep(10000_000)
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
test('test-listen', { skip: SKIP_MANAUAL_TEST }, async () => {
|
|
407
|
+
// node --test-name-pattern="^test-listen$" src/lib.test.js
|
|
408
|
+
await runWithAbortController(async ac => {
|
|
409
|
+
console.info('创建socket服务')
|
|
410
|
+
let transformSize = 0
|
|
411
|
+
let socketServer = net.createServer((socket) => {
|
|
412
|
+
socket.pipe(new Transform({
|
|
413
|
+
transform(chunk, _, callback) {
|
|
414
|
+
// console.info('transform chunk', chunk.length)
|
|
415
|
+
transformSize += chunk.length
|
|
416
|
+
this.push(chunk)
|
|
417
|
+
callback()
|
|
418
|
+
}
|
|
419
|
+
})).pipe(socket)
|
|
420
|
+
}).listen(9036)
|
|
421
|
+
ac.signal.addEventListener('abort', () => { socketServer.close() })
|
|
422
|
+
await sleep(100)
|
|
423
|
+
|
|
424
|
+
console.info('创建监听服务 http')
|
|
425
|
+
let connection = createTunnelTcpClientHttp({
|
|
426
|
+
url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
|
|
427
|
+
signal: ac.signal,
|
|
428
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
429
|
+
})
|
|
430
|
+
connection.listen({
|
|
431
|
+
clientKey: 'mmm',
|
|
432
|
+
tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
|
|
433
|
+
host: '127.0.0.1',
|
|
434
|
+
port: 9036,
|
|
435
|
+
|
|
436
|
+
})
|
|
437
|
+
await sleep(10000_000)
|
|
438
|
+
})
|
|
439
|
+
})
|
|
440
|
+
test('test-connect', { skip: SKIP_MANAUAL_TEST }, async () => {
|
|
441
|
+
// node --test-name-pattern="^test-connect$" src/lib.test.js
|
|
442
|
+
await runWithAbortController(async ac => {
|
|
443
|
+
console.info('创建连接服务 http 1')
|
|
444
|
+
let connection = createTunnelTcpClientHttp({
|
|
445
|
+
url: 'http://127.0.0.1:9035/tunnel/4b34c9275e1089c79327cba18497a37f',
|
|
446
|
+
signal: ac.signal,
|
|
447
|
+
serverKey: '2934c57f790f9e99a52a121802df231c',
|
|
448
|
+
})
|
|
449
|
+
connection.connect({
|
|
450
|
+
clientKey: 'mmm',
|
|
451
|
+
tunnelKey: 'b0f5014acad2060d6bd3730a1721c97f',
|
|
452
|
+
port: 9037,
|
|
453
|
+
})
|
|
454
|
+
await sleep(1000)
|
|
455
|
+
console.info('tcp透传测试 start')
|
|
456
|
+
let socket1 = net.createConnection({ host: '127.0.0.1', port: 9037 })
|
|
457
|
+
|
|
458
|
+
let rec1 = null
|
|
459
|
+
|
|
460
|
+
let sendWriteSize = 0
|
|
461
|
+
let sendSize = 0
|
|
462
|
+
let receiveSize = 0
|
|
463
|
+
let stop = false
|
|
464
|
+
await new Promise((resolve) => {
|
|
465
|
+
// setTimeout(() => {
|
|
466
|
+
// stop = true
|
|
467
|
+
// resolve()
|
|
468
|
+
// }, 5_000)
|
|
469
|
+
socket1.on('connect', async () => {
|
|
470
|
+
socket1.pipe(new Transform({
|
|
471
|
+
async transform(chunk, _, callback) {
|
|
472
|
+
receiveSize += chunk.length
|
|
473
|
+
await sleep(500)
|
|
474
|
+
callback()
|
|
475
|
+
}
|
|
476
|
+
})).on('data', (chunk) => {
|
|
477
|
+
console.info('1 receive chunk ', chunk, Uint8Array_toString(chunk))
|
|
478
|
+
rec1 = Uint8Array_toString(chunk)
|
|
479
|
+
})
|
|
480
|
+
// let data = new Uint8Array(1024 * 1024)
|
|
481
|
+
let data = new Uint8Array(1024)
|
|
482
|
+
// let data = Uint8Array_from('1234567890')
|
|
483
|
+
let readable = new Readable({
|
|
484
|
+
read() {
|
|
485
|
+
if (stop) {
|
|
486
|
+
this.push(null)
|
|
487
|
+
readable.destroy()
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
// data = Uint8Array_from('1234567890')
|
|
491
|
+
sendSize += data.length
|
|
492
|
+
this.push(data)
|
|
493
|
+
// stop = true
|
|
494
|
+
}
|
|
495
|
+
})
|
|
496
|
+
readable.on('data', (chunk) => {
|
|
497
|
+
sendWriteSize += chunk.length
|
|
498
|
+
if (!socket1.write(chunk)) {
|
|
499
|
+
readable.pause()
|
|
500
|
+
}
|
|
501
|
+
})
|
|
502
|
+
socket1.on('drain', () => {
|
|
503
|
+
readable.resume()
|
|
504
|
+
})
|
|
505
|
+
readable.pipe(socket1)
|
|
506
|
+
})
|
|
507
|
+
})
|
|
508
|
+
|
|
509
|
+
await sleep(10000_000)
|
|
510
|
+
})
|
|
511
|
+
})
|