@dainprotocol/tunnel 1.1.6 → 1.1.7
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/dist/client/index.js +51 -6
- package/dist/server/index.js +164 -41
- package/package.json +11 -10
package/dist/client/index.js
CHANGED
|
@@ -136,6 +136,7 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
138
|
handleMessage(message, resolve) {
|
|
139
|
+
console.log(`[Tunnel Client] Received message type: ${message.type}`);
|
|
139
140
|
switch (message.type) {
|
|
140
141
|
case "tunnelUrl":
|
|
141
142
|
this.tunnelUrl = message.url;
|
|
@@ -149,14 +150,18 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
149
150
|
this.handleWebSocketConnection(message);
|
|
150
151
|
break;
|
|
151
152
|
case "sse_connection":
|
|
153
|
+
console.log(`[Tunnel Client] Routing to handleSSEConnection`);
|
|
152
154
|
this.handleSSEConnection(message);
|
|
153
155
|
break;
|
|
154
156
|
case "sse_close":
|
|
157
|
+
console.log(`[Tunnel Client] Routing to handleSSEClose`);
|
|
155
158
|
this.handleSSEClose(message);
|
|
156
159
|
break;
|
|
157
160
|
case "websocket":
|
|
158
161
|
this.handleWebSocketMessage(message);
|
|
159
162
|
break;
|
|
163
|
+
default:
|
|
164
|
+
console.log(`[Tunnel Client] Unknown message type: ${message.type}`);
|
|
160
165
|
}
|
|
161
166
|
}
|
|
162
167
|
async handleRequest(request) {
|
|
@@ -250,6 +255,11 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
250
255
|
}
|
|
251
256
|
}
|
|
252
257
|
handleSSEConnection(message) {
|
|
258
|
+
console.log(`[Tunnel Client] ====== SSE CONNECTION HANDLER START ======`);
|
|
259
|
+
console.log(`[Tunnel Client] SSE ID: ${message.id}`);
|
|
260
|
+
console.log(`[Tunnel Client] Path: ${message.path}`);
|
|
261
|
+
console.log(`[Tunnel Client] Method: ${message.method}`);
|
|
262
|
+
console.log(`[Tunnel Client] Local port: ${this.port}`);
|
|
253
263
|
try {
|
|
254
264
|
// Create an EventSource-like stream to the local server
|
|
255
265
|
// Since Node.js doesn't have a built-in EventSource, we'll use HTTP
|
|
@@ -260,8 +270,13 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
260
270
|
method: message.method || 'GET', // Use provided method (supports POST tool calls)
|
|
261
271
|
headers: message.headers,
|
|
262
272
|
};
|
|
273
|
+
console.log(`[Tunnel Client] Creating HTTP request to: http://localhost:${this.port}${message.path}`);
|
|
274
|
+
console.log(`[Tunnel Client] Request headers:`, JSON.stringify(message.headers, null, 2));
|
|
263
275
|
const req = http_1.default.request(options, (res) => {
|
|
276
|
+
console.log(`[Tunnel Client] Response received with status: ${res.statusCode}`);
|
|
277
|
+
console.log(`[Tunnel Client] Response headers:`, JSON.stringify(res.headers, null, 2));
|
|
264
278
|
if (res.statusCode !== 200) {
|
|
279
|
+
console.error(`[Tunnel Client] ❌ Non-200 status code: ${res.statusCode}`);
|
|
265
280
|
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
266
281
|
this.ws.send(JSON.stringify({
|
|
267
282
|
type: 'sse',
|
|
@@ -272,17 +287,22 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
272
287
|
}
|
|
273
288
|
return;
|
|
274
289
|
}
|
|
290
|
+
console.log(`[Tunnel Client] ✓ Starting SSE stream processing for ${message.id}`);
|
|
275
291
|
// Process SSE stream
|
|
276
292
|
let buffer = '';
|
|
293
|
+
let eventCount = 0;
|
|
277
294
|
res.on('data', (chunk) => {
|
|
278
295
|
const chunkStr = chunk.toString();
|
|
279
|
-
console.log(`[Tunnel Client] SSE chunk received (${chunkStr.length} bytes)
|
|
296
|
+
console.log(`[Tunnel Client] SSE chunk ${++eventCount} received (${chunkStr.length} bytes)`);
|
|
297
|
+
console.log(`[Tunnel Client] Chunk preview:`, chunkStr.substring(0, 200));
|
|
280
298
|
buffer += chunkStr;
|
|
281
299
|
// Process complete SSE messages
|
|
300
|
+
let messagesProcessed = 0;
|
|
282
301
|
while (buffer.includes('\n\n')) {
|
|
283
302
|
const messageEndIndex = buffer.indexOf('\n\n');
|
|
284
303
|
const messageData = buffer.substring(0, messageEndIndex);
|
|
285
304
|
buffer = buffer.substring(messageEndIndex + 2);
|
|
305
|
+
console.log(`[Tunnel Client] Processing SSE message ${++messagesProcessed}:`, messageData);
|
|
286
306
|
// Parse the SSE message
|
|
287
307
|
const lines = messageData.split('\n');
|
|
288
308
|
let event = 'message';
|
|
@@ -300,18 +320,27 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
300
320
|
data = data.substring(0, data.length - 1);
|
|
301
321
|
}
|
|
302
322
|
// Forward to server
|
|
303
|
-
console.log(`[Tunnel Client] Forwarding SSE event
|
|
323
|
+
console.log(`[Tunnel Client] Forwarding SSE event to tunnel server:`);
|
|
324
|
+
console.log(`[Tunnel Client] SSE ID: ${message.id}`);
|
|
325
|
+
console.log(`[Tunnel Client] Event: ${event}`);
|
|
326
|
+
console.log(`[Tunnel Client] Data length: ${data.length}`);
|
|
304
327
|
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
305
|
-
|
|
328
|
+
const forwardMessage = {
|
|
306
329
|
type: 'sse',
|
|
307
330
|
id: message.id,
|
|
308
331
|
event,
|
|
309
332
|
data
|
|
310
|
-
}
|
|
333
|
+
};
|
|
334
|
+
this.ws.send(JSON.stringify(forwardMessage));
|
|
335
|
+
console.log(`[Tunnel Client] ✓ SSE event forwarded to tunnel server`);
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
console.error(`[Tunnel Client] ❌ Cannot forward SSE event - WebSocket not open`);
|
|
311
339
|
}
|
|
312
340
|
}
|
|
313
341
|
});
|
|
314
342
|
res.on('end', () => {
|
|
343
|
+
console.log(`[Tunnel Client] SSE stream ended for ${message.id}`);
|
|
315
344
|
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
316
345
|
this.ws.send(JSON.stringify({
|
|
317
346
|
type: 'sse',
|
|
@@ -319,10 +348,15 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
319
348
|
event: 'close',
|
|
320
349
|
data: 'Connection closed'
|
|
321
350
|
}));
|
|
351
|
+
console.log(`[Tunnel Client] Sent close event to tunnel server`);
|
|
322
352
|
}
|
|
323
353
|
});
|
|
354
|
+
res.on('error', (error) => {
|
|
355
|
+
console.error(`[Tunnel Client] Response stream error for ${message.id}:`, error);
|
|
356
|
+
});
|
|
324
357
|
});
|
|
325
358
|
req.on('error', (error) => {
|
|
359
|
+
console.error(`[Tunnel Client] ❌ Request error for ${message.id}:`, error);
|
|
326
360
|
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
327
361
|
this.ws.send(JSON.stringify({
|
|
328
362
|
type: 'sse',
|
|
@@ -334,15 +368,20 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
334
368
|
});
|
|
335
369
|
// Write request body for POST requests
|
|
336
370
|
if (message.body && message.method !== 'GET') {
|
|
337
|
-
|
|
371
|
+
const bodyBuffer = Buffer.from(message.body, 'base64');
|
|
372
|
+
console.log(`[Tunnel Client] Writing request body (${bodyBuffer.length} bytes)`);
|
|
373
|
+
req.write(bodyBuffer);
|
|
338
374
|
}
|
|
339
375
|
req.end();
|
|
376
|
+
console.log(`[Tunnel Client] Request sent to local service`);
|
|
340
377
|
// Store a reference to abort the connection later if needed
|
|
341
378
|
this.sseClients.set(message.id, req);
|
|
379
|
+
console.log(`[Tunnel Client] SSE client stored. Total SSE clients: ${this.sseClients.size}`);
|
|
342
380
|
this.emit("sse_connection", { id: message.id, path: message.path });
|
|
381
|
+
console.log(`[Tunnel Client] ====== SSE CONNECTION HANDLER COMPLETE ======`);
|
|
343
382
|
}
|
|
344
383
|
catch (error) {
|
|
345
|
-
console.error(
|
|
384
|
+
console.error(`[Tunnel Client] CRITICAL ERROR establishing SSE connection:`, error);
|
|
346
385
|
if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
|
|
347
386
|
this.ws.send(JSON.stringify({
|
|
348
387
|
type: 'sse',
|
|
@@ -354,11 +393,17 @@ class DainTunnel extends events_1.EventEmitter {
|
|
|
354
393
|
}
|
|
355
394
|
}
|
|
356
395
|
handleSSEClose(message) {
|
|
396
|
+
console.log(`[Tunnel Client] SSE close requested for: ${message.id}`);
|
|
357
397
|
const client = this.sseClients.get(message.id);
|
|
358
398
|
if (client) {
|
|
399
|
+
console.log(`[Tunnel Client] Destroying SSE client: ${message.id}`);
|
|
359
400
|
// Abort the request if it's still active
|
|
360
401
|
client.destroy();
|
|
361
402
|
this.sseClients.delete(message.id);
|
|
403
|
+
console.log(`[Tunnel Client] SSE client destroyed. Remaining: ${this.sseClients.size}`);
|
|
404
|
+
}
|
|
405
|
+
else {
|
|
406
|
+
console.log(`[Tunnel Client] SSE client not found: ${message.id}`);
|
|
362
407
|
}
|
|
363
408
|
}
|
|
364
409
|
forwardRequest(request) {
|
package/dist/server/index.js
CHANGED
|
@@ -300,21 +300,54 @@ class DainTunnelServer {
|
|
|
300
300
|
}
|
|
301
301
|
}
|
|
302
302
|
handleSSEMessage(data) {
|
|
303
|
+
var _a;
|
|
304
|
+
console.log(`[Tunnel Server] ====== RECEIVED SSE MESSAGE ======`);
|
|
305
|
+
console.log(`[Tunnel Server] SSE ID: ${data.id}`);
|
|
306
|
+
console.log(`[Tunnel Server] Event: ${data.event}`);
|
|
307
|
+
console.log(`[Tunnel Server] Data length: ${((_a = data.data) === null || _a === void 0 ? void 0 : _a.length) || 0}`);
|
|
308
|
+
console.log(`[Tunnel Server] Active SSE connections: ${this.sseConnections.size}`);
|
|
309
|
+
console.log(`[Tunnel Server] Active SSE IDs: ${Array.from(this.sseConnections.keys()).join(', ')}`);
|
|
303
310
|
const connection = this.sseConnections.get(data.id);
|
|
304
311
|
if (!connection) {
|
|
305
|
-
console.
|
|
312
|
+
console.error(`[Tunnel Server] ❌ SSE connection not found: ${data.id}`);
|
|
313
|
+
console.error(`[Tunnel Server] Available connections: ${Array.from(this.sseConnections.keys()).join(', ')}`);
|
|
314
|
+
console.error(`[Tunnel Server] This means either:`);
|
|
315
|
+
console.error(`[Tunnel Server] 1. The connection was never created (handleSSERequest not called)`);
|
|
316
|
+
console.error(`[Tunnel Server] 2. The connection was already closed`);
|
|
317
|
+
console.error(`[Tunnel Server] 3. There's an ID mismatch`);
|
|
306
318
|
return;
|
|
307
319
|
}
|
|
320
|
+
console.log(`[Tunnel Server] ✓ SSE connection found for ${data.id}`);
|
|
308
321
|
const { res } = connection;
|
|
309
|
-
|
|
310
|
-
|
|
322
|
+
try {
|
|
323
|
+
if (data.event) {
|
|
324
|
+
res.write(`event: ${data.event}\n`);
|
|
325
|
+
console.log(`[Tunnel Server] Wrote event: ${data.event}`);
|
|
326
|
+
}
|
|
327
|
+
// Write data as-is (don't split - data is already properly formatted)
|
|
328
|
+
res.write(`data: ${data.data}\n`);
|
|
329
|
+
res.write('\n');
|
|
330
|
+
console.log(`[Tunnel Server] Wrote ${data.data.length} bytes of data`);
|
|
331
|
+
// Check if this is a "close" event
|
|
332
|
+
if (data.event === 'close') {
|
|
333
|
+
console.log(`[Tunnel Server] Close event received, ending SSE connection ${data.id}`);
|
|
334
|
+
// Clear keepalive interval if it exists
|
|
335
|
+
if (connection.keepaliveInterval) {
|
|
336
|
+
clearInterval(connection.keepaliveInterval);
|
|
337
|
+
console.log(`[Tunnel Server] Cleared keepalive interval for ${data.id}`);
|
|
338
|
+
}
|
|
339
|
+
res.end();
|
|
340
|
+
this.sseConnections.delete(data.id);
|
|
341
|
+
console.log(`[Tunnel Server] SSE connection closed. Remaining: ${this.sseConnections.size}`);
|
|
342
|
+
}
|
|
343
|
+
console.log(`[Tunnel Server] ====== SSE MESSAGE HANDLED ======`);
|
|
311
344
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
345
|
+
catch (error) {
|
|
346
|
+
console.error(`[Tunnel Server] Error writing SSE message for ${data.id}:`, error);
|
|
347
|
+
// Clear keepalive interval if it exists
|
|
348
|
+
if (connection === null || connection === void 0 ? void 0 : connection.keepaliveInterval) {
|
|
349
|
+
clearInterval(connection.keepaliveInterval);
|
|
350
|
+
}
|
|
318
351
|
this.sseConnections.delete(data.id);
|
|
319
352
|
}
|
|
320
353
|
}
|
|
@@ -346,9 +379,14 @@ class DainTunnelServer {
|
|
|
346
379
|
}
|
|
347
380
|
async handleRequest(req, res) {
|
|
348
381
|
const tunnelId = req.params.tunnelId;
|
|
382
|
+
// Log incoming request with headers for debugging
|
|
383
|
+
console.log(`[Tunnel Server] Incoming request: ${req.method} ${req.url} to tunnel ${tunnelId}`);
|
|
384
|
+
console.log(`[Tunnel Server] Accept header: "${req.headers.accept}"`);
|
|
385
|
+
console.log(`[Tunnel Server] Content-Type: "${req.headers['content-type']}"`);
|
|
349
386
|
// Check for upgraded connections (WebSockets) - these are handled by the WebSocket server
|
|
350
387
|
if (req.headers.upgrade && req.headers.upgrade.toLowerCase() === 'websocket') {
|
|
351
388
|
// This is handled by the WebSocket server now
|
|
389
|
+
console.log(`[Tunnel Server] WebSocket upgrade detected, skipping`);
|
|
352
390
|
return;
|
|
353
391
|
}
|
|
354
392
|
let tunnel;
|
|
@@ -366,8 +404,12 @@ class DainTunnelServer {
|
|
|
366
404
|
console.log(`Tunnel not found after retries: ${tunnelId}`);
|
|
367
405
|
return res.status(404).send("Tunnel not found");
|
|
368
406
|
}
|
|
369
|
-
// Check for SSE request
|
|
370
|
-
|
|
407
|
+
// Check for SSE request - more robust check
|
|
408
|
+
const acceptHeader = (req.headers.accept || '').toLowerCase();
|
|
409
|
+
const isSSE = acceptHeader.includes('text/event-stream');
|
|
410
|
+
console.log(`[Tunnel Server] Is SSE request: ${isSSE} (accept: "${acceptHeader}")`);
|
|
411
|
+
if (isSSE) {
|
|
412
|
+
console.log(`[Tunnel Server] Routing to SSE handler`);
|
|
371
413
|
return this.handleSSERequest(req, res, tunnelId, tunnel);
|
|
372
414
|
}
|
|
373
415
|
// Handle regular HTTP request
|
|
@@ -390,37 +432,118 @@ class DainTunnelServer {
|
|
|
390
432
|
handleSSERequest(req, res, tunnelId, tunnel) {
|
|
391
433
|
// Setup SSE connection
|
|
392
434
|
const sseId = (0, uuid_1.v4)();
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
req
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
435
|
+
console.log(`[Tunnel Server] ====== SSE CONNECTION SETUP START ======`);
|
|
436
|
+
console.log(`[Tunnel Server] SSE ID: ${sseId}`);
|
|
437
|
+
console.log(`[Tunnel Server] Tunnel ID: ${tunnelId}`);
|
|
438
|
+
console.log(`[Tunnel Server] Path: ${req.url}`);
|
|
439
|
+
console.log(`[Tunnel Server] Method: ${req.method}`);
|
|
440
|
+
try {
|
|
441
|
+
// CRITICAL: Disable TCP buffering (Nagle's algorithm) to ensure immediate data sending
|
|
442
|
+
// Without this, the initial keepalive may be buffered and not reach the browser,
|
|
443
|
+
// causing it to close the connection immediately
|
|
444
|
+
if (req.socket) {
|
|
445
|
+
req.socket.setNoDelay(true);
|
|
446
|
+
req.socket.setTimeout(0);
|
|
447
|
+
console.log(`[Tunnel Server] Socket configured: noDelay=true, timeout=0 for ${sseId}`);
|
|
448
|
+
}
|
|
449
|
+
res.writeHead(200, {
|
|
450
|
+
'Content-Type': 'text/event-stream',
|
|
451
|
+
'Cache-Control': 'no-cache',
|
|
452
|
+
'Connection': 'keep-alive',
|
|
453
|
+
'X-Accel-Buffering': 'no', // Disable nginx buffering
|
|
454
|
+
'Content-Encoding': 'identity', // Prevent compression middleware from buffering
|
|
455
|
+
'Transfer-Encoding': 'chunked' // Ensure chunked encoding for streaming
|
|
456
|
+
});
|
|
457
|
+
console.log(`[Tunnel Server] SSE headers written for ${sseId}`);
|
|
458
|
+
// Send initial connection event - MUST be sent immediately to prevent browser timeout
|
|
459
|
+
res.write(': keepalive\n\n');
|
|
460
|
+
// Force flush if available (some environments support this)
|
|
461
|
+
if (typeof res.flush === 'function') {
|
|
462
|
+
res.flush();
|
|
463
|
+
console.log(`[Tunnel Server] Response flushed for ${sseId}`);
|
|
464
|
+
}
|
|
465
|
+
console.log(`[Tunnel Server] Initial keepalive sent for ${sseId}`);
|
|
466
|
+
// Send keepalive comments every 5 seconds to prevent timeout
|
|
467
|
+
const keepaliveInterval = setInterval(() => {
|
|
468
|
+
if (this.sseConnections.has(sseId)) {
|
|
469
|
+
try {
|
|
470
|
+
res.write(': keepalive\n\n');
|
|
471
|
+
console.log(`[Tunnel Server] Keepalive sent for ${sseId}`);
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
console.error(`[Tunnel Server] Error sending keepalive for ${sseId}:`, error);
|
|
475
|
+
clearInterval(keepaliveInterval);
|
|
476
|
+
this.sseConnections.delete(sseId);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
clearInterval(keepaliveInterval);
|
|
481
|
+
}
|
|
482
|
+
}, 5000);
|
|
483
|
+
// Store the SSE connection BEFORE notifying tunnel client
|
|
484
|
+
this.sseConnections.set(sseId, {
|
|
485
|
+
req,
|
|
486
|
+
res,
|
|
487
|
+
id: sseId,
|
|
488
|
+
tunnelId,
|
|
489
|
+
keepaliveInterval
|
|
490
|
+
});
|
|
491
|
+
console.log(`[Tunnel Server] SSE connection stored. Total connections: ${this.sseConnections.size}`);
|
|
492
|
+
console.log(`[Tunnel Server] Active SSE IDs: ${Array.from(this.sseConnections.keys()).join(', ')}`);
|
|
493
|
+
// Notify the tunnel client about the new SSE connection
|
|
494
|
+
const sseConnectionMessage = {
|
|
495
|
+
type: "sse_connection",
|
|
496
|
+
id: sseId,
|
|
497
|
+
path: req.url,
|
|
498
|
+
method: req.method, // Include HTTP method for POST tool calls
|
|
499
|
+
headers: req.headers,
|
|
500
|
+
body: req.method !== "GET" && req.body ? req.body.toString("base64") : undefined
|
|
501
|
+
};
|
|
502
|
+
console.log(`[Tunnel Server] Sending sse_connection message to tunnel client`);
|
|
503
|
+
try {
|
|
504
|
+
tunnel.ws.send(JSON.stringify(sseConnectionMessage));
|
|
505
|
+
console.log(`[Tunnel Server] sse_connection message sent successfully for ${sseId}`);
|
|
506
|
+
}
|
|
507
|
+
catch (sendError) {
|
|
508
|
+
console.error(`[Tunnel Server] FAILED to send sse_connection message for ${sseId}:`, sendError);
|
|
509
|
+
// Clean up the SSE connection if we can't notify the client
|
|
510
|
+
this.sseConnections.delete(sseId);
|
|
511
|
+
res.status(500).end();
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
// Handle client disconnect
|
|
515
|
+
req.on('close', () => {
|
|
516
|
+
console.log(`[Tunnel Server] SSE client disconnected: ${sseId}`);
|
|
517
|
+
console.log(`[Tunnel Server] Connection was active for tunnel: ${tunnelId}`);
|
|
518
|
+
clearInterval(keepaliveInterval);
|
|
519
|
+
try {
|
|
520
|
+
tunnel.ws.send(JSON.stringify({
|
|
521
|
+
type: "sse_close",
|
|
522
|
+
id: sseId
|
|
523
|
+
}));
|
|
524
|
+
console.log(`[Tunnel Server] Sent sse_close message for ${sseId}`);
|
|
525
|
+
}
|
|
526
|
+
catch (closeError) {
|
|
527
|
+
console.error(`[Tunnel Server] Error sending sse_close message:`, closeError);
|
|
528
|
+
}
|
|
529
|
+
this.sseConnections.delete(sseId);
|
|
530
|
+
console.log(`[Tunnel Server] SSE connection removed. Remaining: ${this.sseConnections.size}`);
|
|
531
|
+
});
|
|
532
|
+
// Add error handler for the response
|
|
533
|
+
res.on('error', (error) => {
|
|
534
|
+
console.error(`[Tunnel Server] SSE response error for ${sseId}:`, error);
|
|
535
|
+
clearInterval(keepaliveInterval);
|
|
536
|
+
this.sseConnections.delete(sseId);
|
|
537
|
+
});
|
|
538
|
+
console.log(`[Tunnel Server] ====== SSE CONNECTION SETUP COMPLETE ======`);
|
|
539
|
+
}
|
|
540
|
+
catch (error) {
|
|
541
|
+
console.error(`[Tunnel Server] CRITICAL ERROR in handleSSERequest for ${sseId}:`, error);
|
|
422
542
|
this.sseConnections.delete(sseId);
|
|
423
|
-
|
|
543
|
+
if (!res.headersSent) {
|
|
544
|
+
res.status(500).send('SSE setup failed');
|
|
545
|
+
}
|
|
546
|
+
}
|
|
424
547
|
}
|
|
425
548
|
removeTunnel(ws) {
|
|
426
549
|
try {
|
package/package.json
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dainprotocol/tunnel",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"private": false,
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
13
|
+
"test": "jest",
|
|
14
|
+
"test:watch": "jest --watch",
|
|
15
|
+
"prepublishOnly": "npm run build && npm run build:types",
|
|
16
|
+
"start-server": "ts-node src/server/start.ts"
|
|
17
|
+
},
|
|
10
18
|
"keywords": [],
|
|
11
19
|
"author": "Ryan",
|
|
12
20
|
"license": "ISC",
|
|
13
21
|
"dependencies": {
|
|
14
|
-
"@dainprotocol/service-sdk": "^
|
|
22
|
+
"@dainprotocol/service-sdk": "^2.0.31",
|
|
15
23
|
"@types/body-parser": "^1.19.5",
|
|
16
24
|
"@types/cors": "^2.8.17",
|
|
17
25
|
"@types/eventsource": "^3.0.0",
|
|
@@ -68,12 +76,5 @@
|
|
|
68
76
|
"./dist/server/*.d.ts"
|
|
69
77
|
]
|
|
70
78
|
}
|
|
71
|
-
},
|
|
72
|
-
"scripts": {
|
|
73
|
-
"build": "tsc",
|
|
74
|
-
"build:types": "tsc --emitDeclarationOnly",
|
|
75
|
-
"test": "jest",
|
|
76
|
-
"test:watch": "jest --watch",
|
|
77
|
-
"start-server": "ts-node src/server/start.ts"
|
|
78
79
|
}
|
|
79
|
-
}
|
|
80
|
+
}
|