guter zwischenstand
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { FRAME, DATA, ZEPHYR_ERRORS } from './constants';
|
||||
import { protocolInfo, fsInfo } from '../store';
|
||||
import { protocolInfo, fsInfo, transferStats, resetTransferStats, transferDetails } from '../store';
|
||||
import { addToast } from '../toast';
|
||||
import { SETTINGS } from '../settings';
|
||||
import { crc32 } from './crc32';
|
||||
|
||||
let lastUiUpdate = 0;
|
||||
let currentFileCrc32 = 0;
|
||||
|
||||
export type FrameSender = (buffer: ArrayBuffer) => Promise<void>;
|
||||
|
||||
@@ -90,30 +95,42 @@ export function parseIncomingFrame(view: DataView, sender: FrameSender) {
|
||||
break;
|
||||
|
||||
case FRAME.FILE_START:
|
||||
fileTransfer.totalBytes = view.getUint32(3, true);
|
||||
currentFileCrc32 = 0;
|
||||
const totalBytes = view.getUint32(3, true);
|
||||
const nowStart = performance.now();
|
||||
|
||||
transferStats.update(s => ({
|
||||
...s,
|
||||
bytesTotal: totalBytes,
|
||||
bytesDone: 0,
|
||||
currentFileName: s.pendingFileName || s.currentFileName,
|
||||
fileStartTime: nowStart,
|
||||
bulkStartTime: s.bulkStartTime === 0 ? nowStart : s.bulkStartTime
|
||||
}));
|
||||
|
||||
// Parser-interne Metriken (Watchdog etc.)
|
||||
fileTransfer.totalBytes = totalBytes;
|
||||
fileTransfer.receivedBytes = 0;
|
||||
fileTransfer.lastReceivedBytes = 0;
|
||||
fileTransfer.stalledSeconds = 0;
|
||||
fileTransfer.active = true;
|
||||
fileTransfer.startTime = performance.now();
|
||||
|
||||
fileTransfer.startTime = nowStart;
|
||||
lastUiUpdate = 0;
|
||||
|
||||
console.log(`[FILE_GET] Stream gestartet. Erwartete Größe: ${fileTransfer.totalBytes} Bytes.`);
|
||||
|
||||
fileTransfer.metricsTimer = setInterval(() => {
|
||||
if (!fileTransfer.active) return;
|
||||
|
||||
|
||||
// Watchdog-Logik: Prüfen ob seit der letzten Sekunde Daten kamen
|
||||
if (fileTransfer.receivedBytes === fileTransfer.lastReceivedBytes) {
|
||||
fileTransfer.stalledSeconds++;
|
||||
|
||||
|
||||
if (fileTransfer.stalledSeconds >= 5) { // 5 Sekunden Timeout
|
||||
console.warn("[FILE_GET] Übertragung abgebrochen: Timeout (Keine Daten empfangen).");
|
||||
|
||||
|
||||
if (fileTransfer.metricsTimer) clearInterval(fileTransfer.metricsTimer);
|
||||
fileTransfer.active = false;
|
||||
|
||||
// Hier optional einen Toast anzeigen lassen, falls importiert:
|
||||
// addToast("Dateitransfer abgebrochen (Timeout)", "error");
|
||||
|
||||
addToast("Dateitransfer abgebrochen (Timeout)", "error");
|
||||
|
||||
if (fileGetReject) {
|
||||
fileGetReject(new Error("Timeout beim Dateitransfer"));
|
||||
@@ -123,18 +140,9 @@ case FRAME.FILE_START:
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Daten fließen -> Watchdog zurücksetzen
|
||||
fileTransfer.stalledSeconds = 0;
|
||||
fileTransfer.lastReceivedBytes = fileTransfer.receivedBytes;
|
||||
}
|
||||
|
||||
const elapsedSec = (performance.now() - fileTransfer.startTime) / 1000;
|
||||
const speedKB = (fileTransfer.receivedBytes / 1024) / elapsedSec;
|
||||
const percent = fileTransfer.totalBytes > 0
|
||||
? ((fileTransfer.receivedBytes / fileTransfer.totalBytes) * 100).toFixed(1)
|
||||
: "0.0";
|
||||
|
||||
console.log(`[FILE_GET] Fortschritt: ${percent}% | Speed: ${speedKB.toFixed(2)} KB/s`);
|
||||
}, 1000);
|
||||
|
||||
// Initiale Credits (z.B. 64)
|
||||
@@ -145,32 +153,61 @@ case FRAME.FILE_START:
|
||||
case FRAME.FILE_CHUNK:
|
||||
if (!fileTransfer.active) break;
|
||||
|
||||
const chunkData = new Uint8Array(view.buffer, 3, payloadLength);
|
||||
currentFileCrc32 = crc32(chunkData, currentFileCrc32);
|
||||
|
||||
const previousReceived = fileTransfer.receivedBytes;
|
||||
fileTransfer.receivedBytes += payloadLength;
|
||||
fileTransfer.credits--;
|
||||
|
||||
// Nachladen, sobald die Credits auf 32 fallen (Dein Vorschlag)
|
||||
const nowChunk = performance.now();
|
||||
if (nowChunk - lastUiUpdate > SETTINGS.ui.transferUpdateIntervalMs) {
|
||||
const delta = fileTransfer.receivedBytes - previousReceived; // Das Delta seit dem letzten Paket
|
||||
|
||||
transferStats.update(s => ({
|
||||
...s,
|
||||
bytesDone: fileTransfer.receivedBytes,
|
||||
overallDone: s.overallDone + (fileTransfer.receivedBytes - s.bytesDone)
|
||||
}));
|
||||
console.log("[FILE_GET] Fortschritt: " + ((fileTransfer.receivedBytes / fileTransfer.totalBytes) * 100).toFixed(2) + "%");
|
||||
lastUiUpdate = nowChunk;
|
||||
}
|
||||
|
||||
if (fileTransfer.credits <= 64) {
|
||||
fileTransfer.credits = 128;
|
||||
sendCredits(fileTransfer.credits, sender);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case FRAME.FILE_END:
|
||||
if (fileTransfer.metricsTimer) {
|
||||
clearInterval(fileTransfer.metricsTimer);
|
||||
fileTransfer.metricsTimer = null;
|
||||
}
|
||||
transferStats.update(s => {
|
||||
return {
|
||||
...s,
|
||||
bytesDone: s.bytesTotal,
|
||||
};
|
||||
});
|
||||
// Watchdog stoppen
|
||||
if (fileTransfer.metricsTimer) clearInterval(fileTransfer.metricsTimer);
|
||||
fileTransfer.active = false;
|
||||
const buzzerCrc32 = view.getUint32(3, true);
|
||||
|
||||
const crc32 = view.getUint32(3, true);
|
||||
console.log(`[CRC] Lokal: 0x${currentFileCrc32.toString(16).toUpperCase()}`);
|
||||
console.log(`[CRC] Buzzer: 0x${buzzerCrc32.toString(16).toUpperCase()}`);
|
||||
const totalElapsed = (performance.now() - fileTransfer.startTime) / 1000;
|
||||
const avgSpeed = (fileTransfer.receivedBytes / 1024) / totalElapsed;
|
||||
|
||||
console.log(`[FILE_GET] Stream beendet.`);
|
||||
console.log(`[FILE_GET] Empfangen: ${fileTransfer.receivedBytes} Bytes in ${totalElapsed.toFixed(2)}s.`);
|
||||
console.log(`[FILE_GET] Durchschnitt: ${avgSpeed.toFixed(2)} KB/s`);
|
||||
console.log(`[FILE_GET] Zephyr CRC32: 0x${crc32.toString(16).toUpperCase().padStart(8, '0')}`);
|
||||
|
||||
if (currentFileCrc32 === buzzerCrc32) {
|
||||
console.log("%c[CRC] Match! Datei ist integer.", "color: green; font-weight: bold;");
|
||||
} else {
|
||||
console.error("[CRC] Mismatch! Datei beschädigt.");
|
||||
addToast("CRC Fehler: Datei wurde fehlerhaft übertragen.", "error");
|
||||
if (fileGetReject) fileGetReject(new Error("CRC Mismatch"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (fileGetResolve) {
|
||||
fileGetResolve(true);
|
||||
@@ -281,8 +318,8 @@ const fileTransfer = {
|
||||
startTime: 0,
|
||||
totalBytes: 0,
|
||||
receivedBytes: 0,
|
||||
lastReceivedBytes: 0, // NEU: Für die Timeout-Berechnung
|
||||
stalledSeconds: 0, // NEU: Zähler für Stillstand
|
||||
lastReceivedBytes: 0,
|
||||
stalledSeconds: 0,
|
||||
credits: 0,
|
||||
metricsTimer: null as ReturnType<typeof setInterval> | null
|
||||
};
|
||||
@@ -301,7 +338,7 @@ export function buildFileGetRequest(path: string): ArrayBuffer {
|
||||
view.setUint8(0, FRAME.REQUEST);
|
||||
view.setUint16(1, 1 + pathBytes.length, true);
|
||||
view.setUint8(3, DATA.FILE_GET);
|
||||
|
||||
|
||||
const uint8Buffer = new Uint8Array(buffer);
|
||||
uint8Buffer.set(pathBytes, 4);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user