mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-07 16:17:38 +03:00
Merge pull request #6 from swwilshub/claude/websocket-upload-GwiXb
Fix WebSocket upload - reduce chunk size and add stability
This commit is contained in:
commit
bc7e2ac8be
@ -818,7 +818,7 @@
|
|||||||
let failedUploadsGlobal = [];
|
let failedUploadsGlobal = [];
|
||||||
let wsConnection = null;
|
let wsConnection = null;
|
||||||
const WS_PORT = 81;
|
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
|
// Get WebSocket URL based on current page location
|
||||||
function getWsUrl() {
|
function getWsUrl() {
|
||||||
@ -831,6 +831,9 @@ function uploadFileWebSocket(file, onProgress, onComplete, onError) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const ws = new WebSocket(getWsUrl());
|
const ws = new WebSocket(getWsUrl());
|
||||||
let uploadStarted = false;
|
let uploadStarted = false;
|
||||||
|
let sendingChunks = false;
|
||||||
|
|
||||||
|
ws.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
ws.onopen = function() {
|
ws.onopen = function() {
|
||||||
console.log('[WS] Connected, starting upload:', file.name);
|
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.send(`START:${file.name}:${file.size}:${currentPath}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = function(event) {
|
ws.onmessage = async function(event) {
|
||||||
const msg = event.data;
|
const msg = event.data;
|
||||||
console.log('[WS] Message:', msg);
|
console.log('[WS] Message:', msg);
|
||||||
|
|
||||||
if (msg === 'READY') {
|
if (msg === 'READY') {
|
||||||
uploadStarted = true;
|
uploadStarted = true;
|
||||||
// Start sending binary data in chunks
|
sendingChunks = true;
|
||||||
sendFileChunks(ws, file, onProgress);
|
|
||||||
|
// 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:')) {
|
} else if (msg.startsWith('PROGRESS:')) {
|
||||||
|
// Server confirmed progress - we can use this for accurate tracking
|
||||||
const parts = msg.split(':');
|
const parts = msg.split(':');
|
||||||
const received = parseInt(parts[1]);
|
const received = parseInt(parts[1]);
|
||||||
const total = parseInt(parts[2]);
|
const total = parseInt(parts[2]);
|
||||||
@ -866,39 +907,21 @@ function uploadFileWebSocket(file, onProgress, onComplete, onError) {
|
|||||||
ws.onerror = function(event) {
|
ws.onerror = function(event) {
|
||||||
console.error('[WS] Error:', event);
|
console.error('[WS] Error:', event);
|
||||||
if (!uploadStarted) {
|
if (!uploadStarted) {
|
||||||
// WebSocket connection failed, reject to trigger fallback
|
|
||||||
reject(new Error('WebSocket connection failed'));
|
reject(new Error('WebSocket connection failed'));
|
||||||
|
} else if (!sendingChunks) {
|
||||||
|
reject(new Error('WebSocket error during upload'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ws.onclose = function() {
|
ws.onclose = function(event) {
|
||||||
console.log('[WS] Connection closed');
|
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)
|
// Upload file via HTTP (fallback method)
|
||||||
function uploadFileHTTP(file, onProgress, onComplete, onError) {
|
function uploadFileHTTP(file, onProgress, onComplete, onError) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user