diff --git a/src/network/html/FilesPage.html b/src/network/html/FilesPage.html
index 1721faa3..94ec65b3 100644
--- a/src/network/html/FilesPage.html
+++ b/src/network/html/FilesPage.html
@@ -818,7 +818,7 @@
let failedUploadsGlobal = [];
let wsConnection = null;
const WS_PORT = 81;
-const WS_CHUNK_SIZE = 16384; // 16KB chunks for WebSocket - larger = faster
+const WS_CHUNK_SIZE = 4096; // 4KB chunks - smaller for ESP32 stability
// Get WebSocket URL based on current page location
function getWsUrl() {
@@ -831,6 +831,9 @@ function uploadFileWebSocket(file, onProgress, onComplete, onError) {
return new Promise((resolve, reject) => {
const ws = new WebSocket(getWsUrl());
let uploadStarted = false;
+ let sendingChunks = false;
+
+ ws.binaryType = 'arraybuffer';
ws.onopen = function() {
console.log('[WS] Connected, starting upload:', file.name);
@@ -838,15 +841,53 @@ function uploadFileWebSocket(file, onProgress, onComplete, onError) {
ws.send(`START:${file.name}:${file.size}:${currentPath}`);
};
- ws.onmessage = function(event) {
+ ws.onmessage = async function(event) {
const msg = event.data;
console.log('[WS] Message:', msg);
if (msg === 'READY') {
uploadStarted = true;
- // Start sending binary data in chunks
- sendFileChunks(ws, file, onProgress);
+ sendingChunks = true;
+
+ // Small delay to let connection stabilize
+ await new Promise(r => setTimeout(r, 50));
+
+ try {
+ // Send file in chunks
+ const totalSize = file.size;
+ let offset = 0;
+
+ while (offset < totalSize && ws.readyState === WebSocket.OPEN) {
+ const chunkSize = Math.min(WS_CHUNK_SIZE, totalSize - offset);
+ const chunk = file.slice(offset, offset + chunkSize);
+ const buffer = await chunk.arrayBuffer();
+
+ // Wait for buffer to clear - more aggressive backpressure
+ while (ws.bufferedAmount > WS_CHUNK_SIZE * 2 && ws.readyState === WebSocket.OPEN) {
+ await new Promise(r => setTimeout(r, 5));
+ }
+
+ if (ws.readyState !== WebSocket.OPEN) {
+ throw new Error('WebSocket closed during upload');
+ }
+
+ ws.send(buffer);
+ offset += chunkSize;
+
+ // Update local progress
+ if (onProgress) onProgress(offset, totalSize);
+ }
+
+ sendingChunks = false;
+ console.log('[WS] All chunks sent, waiting for DONE');
+ } catch (err) {
+ console.error('[WS] Error sending chunks:', err);
+ sendingChunks = false;
+ ws.close();
+ reject(err);
+ }
} else if (msg.startsWith('PROGRESS:')) {
+ // Server confirmed progress - we can use this for accurate tracking
const parts = msg.split(':');
const received = parseInt(parts[1]);
const total = parseInt(parts[2]);
@@ -866,39 +907,21 @@ function uploadFileWebSocket(file, onProgress, onComplete, onError) {
ws.onerror = function(event) {
console.error('[WS] Error:', event);
if (!uploadStarted) {
- // WebSocket connection failed, reject to trigger fallback
reject(new Error('WebSocket connection failed'));
+ } else if (!sendingChunks) {
+ reject(new Error('WebSocket error during upload'));
}
};
- ws.onclose = function() {
- console.log('[WS] Connection closed');
+ ws.onclose = function(event) {
+ console.log('[WS] Connection closed, code:', event.code, 'reason:', event.reason);
+ if (sendingChunks) {
+ reject(new Error('WebSocket closed unexpectedly'));
+ }
};
});
}
-// Send file in chunks via WebSocket
-async function sendFileChunks(ws, file, onProgress) {
- const totalSize = file.size;
- let offset = 0;
-
- while (offset < totalSize) {
- const chunk = file.slice(offset, offset + WS_CHUNK_SIZE);
- const buffer = await chunk.arrayBuffer();
-
- // Wait for buffer to clear if needed
- while (ws.bufferedAmount > WS_CHUNK_SIZE * 4) {
- await new Promise(r => setTimeout(r, 10));
- }
-
- ws.send(buffer);
- offset += chunk.size;
-
- // Update local progress (server will confirm)
- if (onProgress) onProgress(offset, totalSize);
- }
-}
-
// Upload file via HTTP (fallback method)
function uploadFileHTTP(file, onProgress, onComplete, onError) {
return new Promise((resolve, reject) => {