connectbase-client 3.48.0 → 3.48.2

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 (2) hide show
  1. package/dist/cli.js +41 -6
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -119,6 +119,12 @@ function handleTunnelError(msg, appId, localPort) {
119
119
  exitCode: 1
120
120
  };
121
121
  }
122
+ if (msg.code === "server_shutdown" || msg.error === "server shutting down") {
123
+ return {
124
+ action: "reconnect",
125
+ message: "\uC11C\uBC84\uAC00 \uC7AC\uC2DC\uC791 \uC911\uC785\uB2C8\uB2E4 \u2014 \uC7AC\uC5F0\uACB0\uD569\uB2C8\uB2E4"
126
+ };
127
+ }
122
128
  return {
123
129
  action: "warn",
124
130
  message: `\uD130\uB110 \uC5D0\uB7EC: ${msg.error || msg.message || "\uC54C \uC218 \uC5C6\uB294 \uC5D0\uB7EC"}`
@@ -2364,6 +2370,7 @@ async function startTunnel(port, config, tunnelOpts) {
2364
2370
  const maxReconnectAttempts = 10;
2365
2371
  let shouldReconnect = true;
2366
2372
  let socket = null;
2373
+ let everConnected = false;
2367
2374
  let negotiatedWsOpcode = false;
2368
2375
  let lockReleased = false;
2369
2376
  const releaseLock = () => {
@@ -2417,7 +2424,19 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
2417
2424
  req.on("upgrade", (_res, sock, _head) => {
2418
2425
  socket = sock;
2419
2426
  reconnectAttempts = 0;
2427
+ everConnected = true;
2420
2428
  sock.setNoDelay(true);
2429
+ sock.setKeepAlive(true, 3e4);
2430
+ const idleTimeoutMs = 135e3;
2431
+ let idleTimer = null;
2432
+ const armIdleTimer = () => {
2433
+ if (idleTimer) clearTimeout(idleTimer);
2434
+ idleTimer = setTimeout(() => {
2435
+ warn(`${idleTimeoutMs / 1e3}\uCD08\uAC04 \uC11C\uBC84 \uC218\uC2E0 \uC5C6\uC74C \u2014 \uB04A\uAE34 \uC5F0\uACB0(half-open)\uB85C \uD310\uB2E8\uD558\uACE0 \uC7AC\uC5F0\uACB0\uD569\uB2C8\uB2E4`);
2436
+ sock.destroy();
2437
+ }, idleTimeoutMs);
2438
+ };
2439
+ armIdleTimer();
2421
2440
  const parser = new WsFrameParser({
2422
2441
  onMessage: (data) => {
2423
2442
  try {
@@ -2446,8 +2465,12 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
2446
2465
  sock.write(createWsPongFrame());
2447
2466
  }
2448
2467
  });
2449
- sock.on("data", (chunk) => parser.feed(chunk));
2468
+ sock.on("data", (chunk) => {
2469
+ armIdleTimer();
2470
+ parser.feed(chunk);
2471
+ });
2450
2472
  sock.on("close", () => {
2473
+ if (idleTimer) clearTimeout(idleTimer);
2451
2474
  socket = null;
2452
2475
  if (shouldReconnect) {
2453
2476
  scheduleReconnect();
@@ -2455,6 +2478,7 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
2455
2478
  });
2456
2479
  sock.on("error", (err) => {
2457
2480
  warn(`\uC5F0\uACB0 \uC5D0\uB7EC: ${err.message}`);
2481
+ if (idleTimer) clearTimeout(idleTimer);
2458
2482
  socket = null;
2459
2483
  if (shouldReconnect) {
2460
2484
  scheduleReconnect();
@@ -2507,15 +2531,21 @@ ${colors.cyan}ConnectBase Tunnel${colors.reset}`);
2507
2531
  });
2508
2532
  req.end();
2509
2533
  }
2534
+ let reconnectTimer = null;
2510
2535
  function scheduleReconnect() {
2536
+ if (reconnectTimer) return;
2511
2537
  reconnectAttempts++;
2512
- if (reconnectAttempts > maxReconnectAttempts) {
2538
+ if (!everConnected && reconnectAttempts > maxReconnectAttempts) {
2513
2539
  error("\uCD5C\uB300 \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4 \uD69F\uC218 \uCD08\uACFC");
2514
2540
  process.exit(1);
2515
2541
  }
2516
- const delay = Math.min(2e3 * Math.pow(2, reconnectAttempts - 1), 3e4);
2517
- info(`${(delay / 1e3).toFixed(0)}\uCD08 \uD6C4 \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4... (${reconnectAttempts}/${maxReconnectAttempts})`);
2518
- setTimeout(connect, delay);
2542
+ const delay = Math.min(2e3 * Math.pow(2, Math.min(reconnectAttempts - 1, 8)), 3e4);
2543
+ const attemptLabel = everConnected ? `\uC2DC\uB3C4 ${reconnectAttempts}` : `${reconnectAttempts}/${maxReconnectAttempts}`;
2544
+ info(`${(delay / 1e3).toFixed(0)}\uCD08 \uD6C4 \uC7AC\uC5F0\uACB0 \uC2DC\uB3C4... (${attemptLabel})`);
2545
+ reconnectTimer = setTimeout(() => {
2546
+ reconnectTimer = null;
2547
+ connect();
2548
+ }, delay);
2519
2549
  }
2520
2550
  const streams = /* @__PURE__ */ new Map();
2521
2551
  const localAgent = new http.Agent({ keepAlive: true, maxSockets: 64 });
@@ -2843,10 +2873,15 @@ ${colors.dim}Ctrl+C\uB85C \uC885\uB8CC${colors.reset}
2843
2873
  }
2844
2874
  case "tunnel_error": {
2845
2875
  const result = handleTunnelError(msg, appId, localPort);
2846
- error(result.message);
2847
2876
  if (result.action === "exit") {
2877
+ error(result.message);
2848
2878
  shouldReconnect = false;
2849
2879
  setTimeout(() => process.exit(result.exitCode ?? 1), 500);
2880
+ } else if (result.action === "reconnect") {
2881
+ info(result.message);
2882
+ sock.destroy();
2883
+ } else {
2884
+ error(result.message);
2850
2885
  }
2851
2886
  break;
2852
2887
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "connectbase-client",
3
- "version": "3.48.0",
3
+ "version": "3.48.2",
4
4
  "description": "Connect Base JavaScript/TypeScript SDK for browser and Node.js",
5
5
  "repository": {
6
6
  "type": "git",