batch sizes + client send needed ranges

This commit is contained in:
Klemek
2025-03-20 14:58:01 +01:00
parent 4ca2dcb496
commit f632a8715d
2 changed files with 50 additions and 22 deletions
+2 -2
View File
@@ -32,7 +32,7 @@
<meta name="twitter:image" content="https://file.klemek.fr/preview.jpg" /> <meta name="twitter:image" content="https://file.klemek.fr/preview.jpg" />
</head> </head>
<body data-theme="bumblebee" class="min-h-screen flex flex-col w-screen overflow-y-hidden"> <body data-theme="bumblebee" class="min-h-screen flex flex-col w-screen">
<div class="hero flex-grow bg-base-200"> <div class="hero flex-grow bg-base-200">
<main id="app" class="hero-content text-center" style="display: none"> <main id="app" class="hero-content text-center" style="display: none">
<div class="card w-full max-w-sm bg-base-100/95 shadow-sm"> <div class="card w-full max-w-sm bg-base-100/95 shadow-sm">
@@ -56,7 +56,7 @@
<div v-if="error" class="mt-2 text-error" v-html="error"> <div v-if="error" class="mt-2 text-error" v-html="error">
</div> </div>
<div v-if="fileName" class="mt-2 w-full truncate"> <div v-if="fileName" class="mt-2 w-full truncate">
<code>{{ fileName }}<br>({{ prettyFileSize }})</code> <code class="font-bold">{{ fileName }}<br>({{ prettyFileSize }})</code>
</div> </div>
<template v-if="isServer"> <template v-if="isServer">
<div v-if="serverCanUpload" class="my-t w-full"> <div v-if="serverCanUpload" class="my-t w-full">
+48 -20
View File
@@ -121,6 +121,7 @@ const CONNECTED_STATUSES = [
STATUS.ServerNoFile, STATUS.ServerNoFile,
STATUS.ServerReady, STATUS.ServerReady,
STATUS.ClientConnecting, STATUS.ClientConnecting,
STATUS.ClientDownloading,
STATUS.ClientWaiting, STATUS.ClientWaiting,
STATUS.ClientReady, STATUS.ClientReady,
]; ];
@@ -183,6 +184,7 @@ const PEER_ERROR = {
}; };
const MAX_CHUNK_SIZE = 12 * 1024; const MAX_CHUNK_SIZE = 12 * 1024;
const MAX_BATCH_SIZE = 4096;
const MIN_DELAY_PING = 1000; const MIN_DELAY_PING = 1000;
const MAX_DELAY_PING = MIN_DELAY_PING * 5; const MAX_DELAY_PING = MIN_DELAY_PING * 5;
@@ -450,6 +452,29 @@ const app = createApp({
link.download = this.fileName; link.download = this.fileName;
link.click(); link.click();
}, },
clientGetRemaining() {
const ranges = [];
let currentMin = null;
for (let index = 0; index < this.fileSize; index += MAX_CHUNK_SIZE) {
if (!this.client.received.includes(index)) {
if (currentMin === null) {
currentMin = index;
}
} else if (currentMin !== null) {
ranges.push({
from: currentMin,
to: index - MAX_CHUNK_SIZE,
});
}
}
if (currentMin !== null) {
ranges.push({
from: currentMin,
to: this.fileSize,
});
}
return ranges;
},
clientOpenConnection() { clientOpenConnection() {
this.initClientConnection( this.initClientConnection(
this.peer.connect(this.client.remoteId, { reliable: false }) this.peer.connect(this.client.remoteId, { reliable: false })
@@ -498,6 +523,12 @@ const app = createApp({
this.error = `The remote peer closed the page`; this.error = `The remote peer closed the page`;
} }
break; break;
case PEER_ERROR.Network:
if (this.peer) {
this.error = `Lost connection to server.<br>Reconnecting...`;
this.peer.reconnect();
}
break;
default: default:
if (this.peer) { if (this.peer) {
this.error = `${err.type}.<br>Reconnecting...`; this.error = `${err.type}.<br>Reconnecting...`;
@@ -626,14 +657,9 @@ const app = createApp({
this.server.clients[index].lastSent = new Date(); this.server.clients[index].lastSent = new Date();
}, },
handleServerDone() { handleServerDone() {
const indexes = []; const ranges = this.clientGetRemaining();
for (let index = 0; index < this.fileSize; index += MAX_CHUNK_SIZE) { if (ranges.length) {
if (!this.client.received.includes(index)) { this.sendClientSeek(ranges);
indexes.push(index);
}
}
if (indexes.length) {
this.sendClientSeek(indexes);
} else { } else {
this.client.downloadEnd = new Date(); this.client.downloadEnd = new Date();
this.sendClientDone(); this.sendClientDone();
@@ -656,28 +682,29 @@ const app = createApp({
handleClientInfo(index, data) { handleClientInfo(index, data) {
this.server.clients[index].userAgent = utils.userAgent(data.userAgent); this.server.clients[index].userAgent = utils.userAgent(data.userAgent);
}, },
sendClientSeek(indexes = null) { sendClientSeek(ranges) {
this.client.connection.send({ this.client.connection.send({
type: MESSAGE_TYPE.ClientSeek, type: MESSAGE_TYPE.ClientSeek,
indexes, ranges,
}); });
this.client.lastSent = new Date(); this.client.lastSent = new Date();
}, },
handleClientSeek(index, data) { handleClientSeek(index, data) {
this.server.clients[index].status = STATUS.ClientDownloading; this.server.clients[index].status = STATUS.ClientDownloading;
if (data.indexes) { let sent = 0;
data.indexes.forEach((chunkIndex) => { data.ranges.forEach((range) => {
setTimeout(() => this.sendServerChunk(index, chunkIndex));
});
} else {
for ( for (
let chunkIndex = 0; let chunkIndex = range.from;
chunkIndex < this.fileSize; chunkIndex <= range.to;
chunkIndex += MAX_CHUNK_SIZE chunkIndex += MAX_CHUNK_SIZE
) { ) {
setTimeout(() => this.sendServerChunk(index, chunkIndex)); if (sent >= MAX_BATCH_SIZE) {
break;
}
this.sendServerChunk(index, chunkIndex);
sent += 1;
} }
} });
setTimeout(() => this.sendServerDone(index)); setTimeout(() => this.sendServerDone(index));
}, },
sendClientDone() { sendClientDone() {
@@ -718,7 +745,8 @@ const app = createApp({
} }
this.client.downloadStart = new Date(); this.client.downloadStart = new Date();
this.client.downloadEnd = null; this.client.downloadEnd = null;
this.sendClientSeek(); const indexes = this.clientGetRemaining();
this.sendClientSeek(indexes);
}, },
onShare() { onShare() {
if (navigator.canShare && navigator.canShare()) { if (navigator.canShare && navigator.canShare()) {