diff --git a/bridges/punchd-bridge/gateway/public/js/sw.js b/bridges/punchd-bridge/gateway/public/js/sw.js index 0e82624..c4188f9 100644 --- a/bridges/punchd-bridge/gateway/public/js/sw.js +++ b/bridges/punchd-bridge/gateway/public/js/sw.js @@ -212,6 +212,14 @@ async function handleViaDataChannel(clientId, request) { }, 10000); mc.port1.onmessage = function (e) { + // Progress signal: large response started downloading, extend timeout + if (e.data && e.data.type === "progress") { + clearTimeout(timer); + timer = setTimeout(function () { + resolve(fetch(fallbackRequest)); + }, 300000); // 5 minutes for large downloads (video segments) + return; + } clearTimeout(timer); if (e.data.error) { resolve(fetch(fallbackRequest)); diff --git a/bridges/punchd-bridge/gateway/public/js/webrtc-upgrade.js b/bridges/punchd-bridge/gateway/public/js/webrtc-upgrade.js index ee1548b..a10c813 100644 --- a/bridges/punchd-bridge/gateway/public/js/webrtc-upgrade.js +++ b/bridges/punchd-bridge/gateway/public/js/webrtc-upgrade.js @@ -371,6 +371,20 @@ streaming: true, }); } + } else { + // Buffered streaming (video, large files) — extend timeouts since + // the full response must be received before we can deliver it. + // A 50MB 4K segment over DataChannel can take minutes. + var pending = pendingRequests.get(msg.id); + if (pending) { + clearTimeout(pending.timeout); + pending.timeout = setTimeout(function () { + pendingRequests.delete(msg.id); + pending.port.postMessage({ error: "Timeout" }); + }, 300000); // 5 minutes for large downloads + // Tell SW to extend its timeout too + pending.port.postMessage({ type: "progress" }); + } } // live=true: forward chunks to SW via ReadableStream // live=false: buffer chunks page-side, deliver complete Response on end @@ -641,13 +655,15 @@ }) ); - const timeout = setTimeout(() => { + var timeout = setTimeout(() => { pendingRequests.delete(requestId); streamingPorts.delete(requestId); responsePort.postMessage({ error: "Timeout" }); }, 15000); pendingRequests.set(requestId, { + timeout: timeout, + port: responsePort, resolve: (msg) => { clearTimeout(timeout); if (msg.streaming) { diff --git a/bridges/punchd-bridge/gateway/src/webrtc/peer-handler.ts b/bridges/punchd-bridge/gateway/src/webrtc/peer-handler.ts index 8c59d54..bd9e73c 100644 --- a/bridges/punchd-bridge/gateway/src/webrtc/peer-handler.ts +++ b/bridges/punchd-bridge/gateway/src/webrtc/peer-handler.ts @@ -289,7 +289,7 @@ export function createPeerHandler(options: PeerHandlerOptions): PeerHandler { // Queue-based sending with flow control. // All messages sent as binary to avoid SCTP PPID confusion. - const DC_MAX_BUFFER = 65_536; + const DC_MAX_BUFFER = 512_000; // 512KB — higher buffer for video throughput const queue: { binary: Buffer }[] = []; let scheduled = false; @@ -300,7 +300,7 @@ export function createPeerHandler(options: PeerHandlerOptions): PeerHandler { if (dc.bufferedAmount() > DC_MAX_BUFFER) { res.pause(); scheduled = true; - setTimeout(flush, 5); + setTimeout(flush, 1); return; } try { @@ -308,7 +308,7 @@ export function createPeerHandler(options: PeerHandlerOptions): PeerHandler { if (!sent) { res.pause(); scheduled = true; - setTimeout(flush, 10); + setTimeout(flush, 2); return; } } catch {