Fix Tunnel

This commit is contained in:
decolua
2026-03-20 00:26:01 +07:00
parent 80583e203d
commit 6af8043f2a
3 changed files with 31 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "9router-app",
"version": "0.3.58",
"version": "0.3.60",
"description": "9Router web dashboard",
"private": true,
"scripts": {

View File

@@ -217,6 +217,23 @@ export async function spawnQuickTunnel(localPort, onUrlUpdate) {
return new Promise((resolve, reject) => {
let resolved = false;
function getQuickTunnelUrlFromLog(message) {
// cloudflared logs may contain "api.trycloudflare.com" as well,
// but that is NOT the quick-tunnel endpoint we need.
const regex = /https:\/\/([a-z0-9-]+)\.trycloudflare\.com/gi;
const candidates = [];
for (const match of message.matchAll(regex)) {
const host = match[1];
if (host === "api") continue;
candidates.push(`https://${host}.trycloudflare.com`);
}
if (!candidates.length) return null;
return candidates[candidates.length - 1];
}
const timeout = setTimeout(() => {
if (resolved) return;
resolved = true;
@@ -226,10 +243,8 @@ export async function spawnQuickTunnel(localPort, onUrlUpdate) {
const handleLog = (data) => {
const msg = data.toString();
// Parse trycloudflare.com URL from cloudflared output
const match = msg.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);
if (match && !resolved) {
const tunnelUrl = match[0];
const tunnelUrl = getQuickTunnelUrlFromLog(msg);
if (tunnelUrl && !resolved) {
resolved = true;
clearTimeout(timeout);
cleanup();

View File

@@ -11,6 +11,7 @@ const RECONNECT_DELAYS_MS = [5000, 10000, 20000, 30000, 60000];
const MAX_RECONNECT_ATTEMPTS = RECONNECT_DELAYS_MS.length;
let isReconnecting = false;
let exitHandlerRegistered = false;
function generateShortId() {
let result = "";
@@ -68,11 +69,16 @@ export async function enableTunnel(localPort = 20128) {
saveState({ shortId, machineId, tunnelUrl });
await updateSettings({ tunnelEnabled: true, tunnelUrl });
setUnexpectedExitHandler(() => {
if (!isReconnecting) scheduleReconnect(0);
});
// Set exit handler only once (not on every reconnect)
if (!exitHandlerRegistered) {
setUnexpectedExitHandler(() => {
if (!isReconnecting) scheduleReconnect(0);
});
exitHandlerRegistered = true;
}
return { success: true, tunnelUrl, shortId };
const publicUrl = `https://r${shortId}.9router.com`;
return { success: true, tunnelUrl, shortId, publicUrl };
}
async function scheduleReconnect(attempt) {
@@ -104,6 +110,7 @@ async function scheduleReconnect(attempt) {
export async function disableTunnel() {
killCloudflared();
exitHandlerRegistered = false; // Reset handler flag when tunnel disabled
const state = loadState();
if (state) {